From bf8ae351a54f1ec0e91f35866464d3cee9408cf7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Thu, 19 Mar 2026 11:37:06 +0000 Subject: [PATCH 001/900] New queries for terraform, Azure GCP IBM and OCI --- .../README.md | 46 +++++++ .../metadata.json | 13 ++ .../query.rego | 44 +++++++ .../test/negative1.tf | 11 ++ .../test/negative2.tf | 11 ++ .../test/positive1.tf | 6 + .../test/positive2.tf | 10 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 55 ++++++++ .../metadata.json | 13 ++ .../query.rego | 38 ++++++ .../test/negative1.tf | 15 +++ .../test/positive1.tf | 8 ++ .../test/positive2.tf | 13 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 37 ++++++ .../metadata.json | 13 ++ .../query.rego | 25 ++++ .../test/negative1.tf | 16 +++ .../test/positive1.tf | 11 ++ .../test/positive_expected_result.json | 8 ++ .../README.md | 47 +++++++ .../metadata.json | 13 ++ .../query.rego | 33 +++++ .../test/negative1.tf | 9 ++ .../test/positive1.tf | 8 ++ .../test/positive2.tf | 9 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 42 ++++++ .../metadata.json | 13 ++ .../query.rego | 17 +++ .../test/negative1.tf | 11 ++ .../test/positive1.tf | 8 ++ .../test/positive_expected_result.json | 8 ++ .../azure_bastion_host_missing/README.md | 50 +++++++ .../azure_bastion_host_missing/metadata.json | 13 ++ .../azure_bastion_host_missing/query.rego | 20 +++ .../test/negative1.tf | 18 +++ .../test/positive1.tf | 6 + .../test/positive_expected_result.json | 8 ++ .../README.md | 36 ++++++ .../metadata.json | 13 ++ .../query.rego | 15 +++ .../test/positive1.tf | 4 + .../test/positive_expected_result.json | 8 ++ .../README.md | 52 ++++++++ .../metadata.json | 13 ++ .../query.rego | 18 +++ .../test/negative1.tf | 8 ++ .../test/positive1.tf | 5 + .../test/positive_expected_result.json | 8 ++ .../README.md | 68 ++++++++++ .../metadata.json | 13 ++ .../query.rego | 38 ++++++ .../test/negative1.tf | 14 ++ .../test/positive1.tf | 5 + .../test/positive2.tf | 6 + .../test/positive_expected_result.json | 14 ++ .../azure_iot_hub_defender_disabled/README.md | 72 +++++++++++ .../metadata.json | 13 ++ .../query.rego | 33 +++++ .../test/negative1.tf | 18 +++ .../test/positive1.tf | 10 ++ .../test/positive_expected_result.json | 8 ++ .../README.md | 64 +++++++++ .../metadata.json | 13 ++ .../query.rego | 17 +++ .../test/negative1.tf | 16 +++ .../test/positive1.tf | 7 + .../test/positive_expected_result.json | 8 ++ .../README.md | 60 +++++++++ .../metadata.json | 13 ++ .../query.rego | 17 +++ .../test/negative1.tf | 13 ++ .../test/positive1.tf | 8 ++ .../test/positive_expected_result.json | 8 ++ .../README.md | 59 +++++++++ .../metadata.json | 13 ++ .../query.rego | 19 +++ .../test/positive1.tf | 8 ++ .../test/positive2.tf | 7 + .../test/positive_expected_result.json | 14 ++ .../README.md | 59 +++++++++ .../metadata.json | 13 ++ .../query.rego | 19 +++ .../test/positive1.tf | 8 ++ .../test/positive2.tf | 7 + .../test/positive_expected_result.json | 14 ++ .../README.md | 65 ++++++++++ .../metadata.json | 13 ++ .../query.rego | 36 ++++++ .../test/negative1.tf | 16 +++ .../test/positive1.tf | 5 + .../test/positive_expected_result.json | 8 ++ .../README.md | 67 ++++++++++ .../metadata.json | 13 ++ .../query.rego | 54 ++++++++ .../test/negative1.tf | 22 ++++ .../test/positive1.tf | 7 + .../test/positive2.tf | 7 + .../test/positive_expected_result.json | 14 ++ .../README.md | 69 ++++++++++ .../metadata.json | 13 ++ .../query.rego | 34 +++++ .../test/negative1.tf | 7 + .../test/negative2.tf | 8 ++ .../test/positive1.tf | 7 + .../test/positive2.tf | 8 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 61 +++++++++ .../metadata.json | 13 ++ .../query.rego | 17 +++ .../test/negative1.tf | 16 +++ .../test/positive1.tf | 7 + .../test/positive_expected_result.json | 8 ++ .../README.md | 72 +++++++++++ .../metadata.json | 13 ++ .../query.rego | 33 +++++ .../test/negative1.tf | 8 ++ .../test/positive1.tf | 7 + .../test/positive2.tf | 8 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 79 ++++++++++++ .../metadata.json | 13 ++ .../query.rego | 34 +++++ .../test/negative1.tf | 16 +++ .../test/positive1.tf | 6 + .../test/positive2.tf | 12 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 56 ++++++++ .../metadata.json | 13 ++ .../query.rego | 32 +++++ .../test/negative1.tf | 13 ++ .../test/positive1.tf | 8 ++ .../test/positive_expected_result.json | 8 ++ .../README.md | 55 ++++++++ .../metadata.json | 13 ++ .../query.rego | 21 +++ .../test/negative1.tf | 7 + .../test/positive1.tf | 7 + .../test/positive_expected_result.json | 8 ++ .../README.md | 72 +++++++++++ .../metadata.json | 13 ++ .../query.rego | 33 +++++ .../test/negative1.tf | 8 ++ .../test/positive1.tf | 7 + .../test/positive2.tf | 8 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 63 +++++++++ .../metadata.json | 13 ++ .../query.rego | 58 +++++++++ .../test/negative1.tf | 13 ++ .../test/positive1.tf | 7 + .../test/positive2.tf | 13 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 76 +++++++++++ .../metadata.json | 13 ++ .../query.rego | 51 ++++++++ .../test/negative1.tf | 11 ++ .../test/positive1.tf | 7 + .../test/positive2.tf | 11 ++ .../test/positive3.tf | 11 ++ .../test/positive_expected_result.json | 20 +++ .../README.md | 46 +++++++ .../metadata.json | 13 ++ .../query.rego | 76 +++++++++++ .../test/negative1.tf | 17 +++ .../test/positive1.tf | 7 + .../test/positive2.tf | 6 + .../test/positive3.tf | 10 ++ .../test/positive_expected_result.json | 20 +++ .../README.md | 65 ++++++++++ .../metadata.json | 13 ++ .../query.rego | 33 +++++ .../test/negative1.tf | 5 + .../test/positive1.tf | 4 + .../test/positive2.tf | 5 + .../test/positive_expected_result.json | 14 ++ .../README.md | 62 +++++++++ .../metadata.json | 13 ++ .../query.rego | 34 +++++ .../test/negative1.tf | 16 +++ .../test/positive1.tf | 7 + .../test/positive2.tf | 11 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 93 +++++++++++++ .../metadata.json | 13 ++ .../query.rego | 74 +++++++++++ .../test/negative1.tf | 17 +++ .../test/negative2.tf | 19 +++ .../test/positive1.tf | 11 ++ .../test/positive2.tf | 16 +++ .../test/positive3.tf | 3 + .../test/positive4.tf | 9 ++ .../test/positive_expected_result.json | 26 ++++ .../README.md | 52 ++++++++ .../metadata.json | 13 ++ .../query.rego | 76 +++++++++++ .../test/negative1.tf | 17 +++ .../test/positive1.tf | 7 + .../test/positive2.tf | 6 + .../test/positive3.tf | 18 +++ .../test/positive_expected_result.json | 20 +++ .../gcp_access_approval_disabled/README.md | 50 +++++++ .../metadata.json | 13 ++ .../gcp_access_approval_disabled/query.rego | 38 ++++++ .../test/negative1.tf | 13 ++ .../test/positive1.tf | 5 + .../test/positive2.tf | 4 + .../test/positive_expected_result.json | 14 ++ .../gcp_api_key_api_targets_missing/README.md | 57 ++++++++ .../metadata.json | 13 ++ .../query.rego | 34 +++++ .../test/negative1.tf | 15 +++ .../test/positive1.tf | 5 + .../test/positive2.tf | 11 ++ .../test/positive_expected_result.json | 14 ++ .../gcp_api_key_restrictions_manual/README.md | 54 ++++++++ .../metadata.json | 13 ++ .../query.rego | 33 +++++ .../test/negative1.tf | 4 + .../test/positive1.tf | 6 + .../test/positive2.tf | 11 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 57 ++++++++ .../metadata.json | 13 ++ .../query.rego | 42 ++++++ .../test/negative1.tf | 10 ++ .../test/positive1.tf | 11 ++ .../test/positive2.tf | 6 + .../test/positive_expected_result.json | 14 ++ .../README.md | 49 +++++++ .../metadata.json | 13 ++ .../query.rego | 51 ++++++++ .../test/negative1.tf | 6 + .../test/positive1.tf | 4 + .../test/positive2.tf | 6 + .../test/positive3.tf | 6 + .../test/positive_expected_result.json | 20 +++ .../README.md | 51 ++++++++ .../metadata.json | 13 ++ .../query.rego | 33 +++++ .../test/negative1.tf | 6 + .../test/positive1.tf | 9 ++ .../test/positive2.tf | 9 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 46 +++++++ .../metadata.json | 13 ++ .../query.rego | 51 ++++++++ .../test/negative1.tf | 8 ++ .../test/negative2.tf | 8 ++ .../test/positive1.tf | 5 + .../test/positive2.tf | 8 ++ .../test/positive3.tf | 8 ++ .../test/positive_expected_result.json | 20 +++ .../gcp/gcp_gke_manual_iam_check/README.md | 38 ++++++ .../gcp_gke_manual_iam_check/metadata.json | 13 ++ .../gcp/gcp_gke_manual_iam_check/query.rego | 33 +++++ .../test/negative1.tf | 5 + .../test/positive1.tf | 9 ++ .../test/positive2.tf | 9 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 47 +++++++ .../metadata.json | 13 ++ .../query.rego | 65 ++++++++++ .../test/negative1.tf | 8 ++ .../test/negative2.tf | 9 ++ .../test/positive1.tf | 9 ++ .../test/positive2.tf | 9 ++ .../test/positive3.tf | 9 ++ .../test/positive4.tf | 10 ++ .../test/positive_expected_result.json | 26 ++++ .../gcp/gcp_gke_sandbox_disabled/README.md | 52 ++++++++ .../gcp_gke_sandbox_disabled/metadata.json | 13 ++ .../gcp/gcp_gke_sandbox_disabled/query.rego | 65 ++++++++++ .../test/negative1.tf | 12 ++ .../test/negative2.tf | 12 ++ .../test/positive1.tf | 9 ++ .../test/positive2.tf | 9 ++ .../test/positive3.tf | 9 ++ .../test/positive4.tf | 10 ++ .../test/positive_expected_result.json | 26 ++++ .../README.md | 50 +++++++ .../metadata.json | 13 ++ .../query.rego | 52 ++++++++ .../test/negative1.tf | 8 ++ .../test/positive1.tf | 5 + .../test/positive2.tf | 8 ++ .../test/positive3.tf | 8 ++ .../test/positive_expected_result.json | 20 +++ .../gcp_gke_security_posture_manual/README.md | 45 +++++++ .../metadata.json | 13 ++ .../query.rego | 33 +++++ .../test/negative1.tf | 6 + .../test/negative2.tf | 6 + .../test/positive1.tf | 5 + .../test/positive2.tf | 7 + .../test/positive_expected_result.json | 14 ++ .../README.md | 54 ++++++++ .../metadata.json | 13 ++ .../query.rego | 33 +++++ .../test/negative1.tf | 4 + .../test/positive1.tf | 5 + .../test/positive2.tf | 8 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 47 +++++++ .../metadata.json | 13 ++ .../query.rego | 33 +++++ .../test/negative1.tf | 8 ++ .../test/positive1.tf | 5 + .../test/positive2.tf | 7 + .../test/positive_expected_result.json | 14 ++ .../README.md | 53 ++++++++ .../metadata.json | 13 ++ .../query.rego | 51 ++++++++ .../test/negative1.tf | 8 ++ .../test/positive1.tf | 4 + .../test/positive2.tf | 6 + .../test/positive3.tf | 6 + .../test/positive_expected_result.json | 20 +++ .../README.md | 40 ++++++ .../metadata.json | 13 ++ .../query.rego | 25 ++++ .../test/negative1.tf | 11 ++ .../test/positive1.tf | 12 ++ .../test/positive2.tf | 18 +++ .../test/positive_expected_result.json | 14 ++ .../README.md | 51 ++++++++ .../metadata.json | 13 ++ .../query.rego | 49 +++++++ .../test/negative1.tf | 11 ++ .../test/positive1.tf | 12 ++ .../test/positive2.tf | 11 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 65 ++++++++++ .../metadata.json | 13 ++ .../query.rego | 40 ++++++ .../test/negative1.tf | 10 ++ .../test/positive1.tf | 7 + .../test/positive2.tf | 10 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 86 ++++++++++++ .../metadata.json | 13 ++ .../query.rego | 54 ++++++++ .../test/negative1.tf | 11 ++ .../test/positive1.tf | 8 ++ .../test/positive2.tf | 11 ++ .../test/positive3.tf | 13 ++ .../test/positive_expected_result.json | 20 +++ .../README.md | 58 +++++++++ .../metadata.json | 13 ++ .../query.rego | 17 +++ .../test/negative1.tf | 12 ++ .../test/positive1.tf | 10 ++ .../test/positive_expected_result.json | 8 ++ .../README.md | 65 ++++++++++ .../metadata.json | 13 ++ .../query.rego | 33 +++++ .../test/negative1.tf | 8 ++ .../test/positive1.tf | 6 + .../test/positive2.tf | 8 ++ .../test/positive_expected_result.json | 14 ++ .../ibm_cis_dns_not_proxied_manual/README.md | 77 +++++++++++ .../metadata.json | 13 ++ .../ibm_cis_dns_not_proxied_manual/query.rego | 33 +++++ .../test/negative1.tf | 10 ++ .../test/positive1.tf | 10 ++ .../test/positive2.tf | 8 ++ .../test/positive_expected_result.json | 14 ++ .../ibm/ibm_cis_waf_enabled_manual/README.md | 72 +++++++++++ .../ibm_cis_waf_enabled_manual/metadata.json | 13 ++ .../ibm/ibm_cis_waf_enabled_manual/query.rego | 34 +++++ .../test/negative1.tf | 7 + .../test/positive1.tf | 7 + .../test/positive2.tf | 6 + .../test/positive_expected_result.json | 14 ++ .../README.md | 75 +++++++++++ .../metadata.json | 13 ++ .../query.rego | 36 ++++++ .../test/negative1.tf | 10 ++ .../test/positive1.tf | 6 + .../test/positive2.tf | 10 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 62 +++++++++ .../metadata.json | 13 ++ .../query.rego | 17 +++ .../test/negative1.tf | 15 +++ .../test/positive1.tf | 13 ++ .../test/positive_expected_result.json | 8 ++ .../README.md | 54 ++++++++ .../metadata.json | 13 ++ .../query.rego | 19 +++ .../test/negative1.tf | 18 +++ .../test/positive1.tf | 13 ++ .../test/positive_expected_result.json | 8 ++ .../README.md | 60 +++++++++ .../metadata.json | 13 ++ .../query.rego | 17 +++ .../test/negative1.tf | 13 ++ .../test/positive1.tf | 11 ++ .../test/positive_expected_result.json | 8 ++ .../README.md | 57 ++++++++ .../metadata.json | 13 ++ .../query.rego | 17 +++ .../test/negative1.tf | 13 ++ .../test/positive1.tf | 11 ++ .../test/positive_expected_result.json | 8 ++ .../README.md | 69 ++++++++++ .../metadata.json | 13 ++ .../query.rego | 34 +++++ .../test/negative1.tf | 7 + .../test/positive1.tf | 4 + .../test/positive2.tf | 3 + .../test/positive_expected_result.json | 14 ++ .../ibm_iam_account_mfa_disabled/README.md | 46 +++++++ .../metadata.json | 13 ++ .../ibm_iam_account_mfa_disabled/query.rego | 50 +++++++ .../test/negative1.tf | 4 + .../test/positive1.tf | 8 ++ .../test/positive2.tf | 4 + .../test/positive3.tf | 4 + .../test/positive_expected_result.json | 20 +++ .../ibm_iam_api_key_unused_manual/README.md | 60 +++++++++ .../metadata.json | 13 ++ .../ibm_iam_api_key_unused_manual/query.rego | 29 +++++ .../test/negative1.tf | 8 ++ .../test/positive1.tf | 3 + .../test/positive2.tf | 4 + .../test/positive_expected_result.json | 14 ++ .../ibm_iam_owner_api_key_manual/README.md | 50 +++++++ .../metadata.json | 13 ++ .../ibm_iam_owner_api_key_manual/query.rego | 15 +++ .../test/negative1.tf | 9 ++ .../test/positive1.tf | 3 + .../test/positive_expected_result.json | 8 ++ .../README.md | 65 ++++++++++ .../metadata.json | 13 ++ .../query.rego | 15 +++ .../test/negative1.tf | 14 ++ .../test/positive1.tf | 8 ++ .../test/positive_expected_result.json | 8 ++ .../README.md | 50 +++++++ .../metadata.json | 13 ++ .../query.rego | 38 ++++++ .../test/negative1.tf | 4 + .../test/positive1.tf | 8 ++ .../test/positive2.tf | 8 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 56 ++++++++ .../metadata.json | 13 ++ .../query.rego | 35 +++++ .../test/negative1.tf | 4 + .../test/positive1.tf | 3 + .../test/positive2.tf | 3 + .../test/positive_expected_result.json | 14 ++ .../README.md | 55 ++++++++ .../metadata.json | 13 ++ .../query.rego | 21 +++ .../test/negative1.tf | 13 ++ .../test/positive1.tf | 8 ++ .../test/positive_expected_result.json | 8 ++ .../README.md | 55 ++++++++ .../metadata.json | 13 ++ .../query.rego | 22 ++++ .../test/negative1.tf | 11 ++ .../test/positive1.tf | 8 ++ .../test/positive_expected_result.json | 8 ++ .../README.md | 51 ++++++++ .../metadata.json | 13 ++ .../query.rego | 39 ++++++ .../test/negative1.tf | 10 ++ .../test/positive1.tf | 8 ++ .../test/positive2.tf | 10 ++ .../test/positive_expected_result.json | 14 ++ .../ibm_kms_key_rotation_disabled/README.md | 63 +++++++++ .../metadata.json | 13 ++ .../ibm_kms_key_rotation_disabled/query.rego | 47 +++++++ .../test/negative1.tf | 9 ++ .../test/positive1.tf | 5 + .../test/positive2.tf | 9 ++ .../test/positive3.tf | 9 ++ .../test/positive_expected_result.json | 20 +++ .../ibm_logdna_archiving_disabled/README.md | 53 ++++++++ .../metadata.json | 13 ++ .../ibm_logdna_archiving_disabled/query.rego | 22 ++++ .../test/negative1.tf | 15 +++ .../test/positive1.tf | 5 + .../test/positive_expected_result.json | 8 ++ .../ibm_logdna_view_without_alert/README.md | 51 ++++++++ .../metadata.json | 13 ++ .../ibm_logdna_view_without_alert/query.rego | 22 ++++ .../test/negative1.tf | 15 +++ .../test/positive1.tf | 4 + .../test/positive_expected_result.json | 8 ++ .../README.md | 95 ++++++++++++++ .../metadata.json | 13 ++ .../query.rego | 24 ++++ .../test/negative1.tf | 17 +++ .../test/positive1.tf | 9 ++ .../test/positive2.tf | 17 +++ .../test/positive3.tf | 17 +++ .../test/positive_expected_result.json | 20 +++ .../README.md | 76 +++++++++++ .../metadata.json | 13 ++ .../query.rego | 52 ++++++++ .../test/negative1.tf | 10 ++ .../test/positive1.tf | 9 ++ .../test/positive2.tf | 9 ++ .../test/positive3.tf | 10 ++ .../test/positive_expected_result.json | 20 +++ .../README.md | 71 ++++++++++ .../metadata.json | 13 ++ .../query.rego | 48 +++++++ .../test/negative1.tf | 10 ++ .../test/positive1.tf | 6 + .../test/positive2.tf | 10 ++ .../test/positive3.tf | 10 ++ .../test/positive_expected_result.json | 20 +++ .../README.md | 73 +++++++++++ .../metadata.json | 13 ++ .../query.rego | 48 +++++++ .../test/negative1.tf | 10 ++ .../test/positive1.tf | 6 + .../test/positive2.tf | 10 ++ .../test/positive3.tf | 10 ++ .../test/positive_expected_result.json | 20 +++ .../oci_default_tags_not_defined/README.md | 69 ++++++++++ .../metadata.json | 13 ++ .../oci_default_tags_not_defined/query.rego | 20 +++ .../test/negative1.tf | 22 ++++ .../test/positive1.tf | 8 ++ .../test/positive_expected_result.json | 8 ++ .../README.md | 122 ++++++++++++++++++ .../metadata.json | 13 ++ .../query.rego | 77 +++++++++++ .../test/negative1.tf | 23 ++++ .../test/positive1.tf | 8 ++ .../test/positive2.tf | 20 +++ .../test/positive3.tf | 24 ++++ .../test/positive_expected_result.json | 20 +++ .../README.md | 49 +++++++ .../metadata.json | 13 ++ .../query.rego | 47 +++++++ .../test/negative1.tf | 7 + .../test/positive1.tf | 7 + .../test/positive2.tf | 7 + .../test/positive3.tf | 7 + .../test/positive_expected_result.json | 20 +++ .../oci_iam_password_policy_length/README.md | 55 ++++++++ .../metadata.json | 13 ++ .../oci_iam_password_policy_length/query.rego | 62 +++++++++ .../test/negative1.tf | 9 ++ .../test/positive1.tf | 9 ++ .../test/positive2.tf | 8 ++ .../test/positive3.tf | 4 + .../test/positive_expected_result.json | 20 +++ .../oci_iam_password_reuse_manual/README.md | 55 ++++++++ .../metadata.json | 13 ++ .../oci_iam_password_reuse_manual/query.rego | 47 +++++++ .../test/negative1.tf | 9 ++ .../test/positive1.tf | 9 ++ .../test/positive2.tf | 8 ++ .../test/positive3.tf | 8 ++ .../test/positive_expected_result.json | 20 +++ .../README.md | 65 ++++++++++ .../metadata.json | 13 ++ .../query.rego | 76 +++++++++++ .../test/negative1.tf | 25 ++++ .../test/positive1.tf | 10 ++ .../test/positive2.tf | 25 ++++ .../test/positive3.tf | 26 ++++ .../test/positive_expected_result.json | 20 +++ .../oci_iam_service_admins_manual/README.md | 46 +++++++ .../metadata.json | 13 ++ .../oci_iam_service_admins_manual/query.rego | 19 +++ .../test/negative1.tf | 14 ++ .../test/negative2.tf | 13 ++ .../test/positive1.tf | 23 ++++ .../test/positive_expected_result.json | 14 ++ .../README.md | 57 ++++++++ .../metadata.json | 13 ++ .../query.rego | 78 +++++++++++ .../test/negative1.tf | 27 ++++ .../test/positive1.tf | 8 ++ .../test/positive2.tf | 25 ++++ .../test/positive3.tf | 28 ++++ .../test/positive_expected_result.json | 20 +++ .../README.md | 47 +++++++ .../metadata.json | 13 ++ .../query.rego | 43 ++++++ .../test/negative1.tf | 23 ++++ .../test/positive1.tf | 20 +++ .../test/positive2.tf | 24 ++++ .../test/positive_expected_result.json | 14 ++ .../README.md | 45 +++++++ .../metadata.json | 13 ++ .../query.rego | 43 ++++++ .../test/negative1.tf | 23 ++++ .../test/positive1.tf | 20 +++ .../test/positive2.tf | 24 ++++ .../test/positive_expected_result.json | 14 ++ .../oci_instance_transit_encryption/README.md | 54 ++++++++ .../metadata.json | 13 ++ .../query.rego | 58 +++++++++ .../test/negative1.tf | 14 ++ .../test/positive1.tf | 20 +++ .../test/positive2.tf | 15 +++ .../test/positive3.tf | 15 +++ .../test/positive_expected_result.json | 20 +++ .../README.md | 45 +++++++ .../metadata.json | 13 ++ .../query.rego | 43 ++++++ .../test/negative1.tf | 23 ++++ .../test/positive1.tf | 20 +++ .../test/positive2.tf | 24 ++++ .../test/positive_expected_result.json | 14 ++ .../README.md | 67 ++++++++++ .../metadata.json | 13 ++ .../query.rego | 88 +++++++++++++ .../test/negative1.tf | 43 ++++++ .../test/positive1.tf | 8 ++ .../test/positive2.tf | 25 ++++ .../test/positive3.tf | 38 ++++++ .../test/positive_expected_result.json | 20 +++ .../README.md | 44 +++++++ .../metadata.json | 13 ++ .../query.rego | 44 +++++++ .../test/negative1.tf | 16 +++ .../test/positive1.tf | 8 ++ .../test/positive2.tf | 9 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 53 ++++++++ .../metadata.json | 13 ++ .../query.rego | 76 +++++++++++ .../test/negative1.tf | 25 ++++ .../test/positive1.tf | 9 ++ .../test/positive2.tf | 24 ++++ .../test/positive3.tf | 26 ++++ .../test/positive_expected_result.json | 20 +++ .../README.md | 34 +++++ .../metadata.json | 13 ++ .../query.rego | 32 +++++ .../test/negative1.tf | 12 ++ .../test/positive1.tf | 11 ++ .../test/positive2.tf | 12 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 34 +++++ .../metadata.json | 13 ++ .../query.rego | 34 +++++ .../test/negative1.tf | 12 ++ .../test/positive1.tf | 11 ++ .../test/positive2.tf | 12 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 35 +++++ .../metadata.json | 13 ++ .../query.rego | 52 ++++++++ .../test/negative1.tf | 17 +++ .../test/positive1.tf | 12 ++ .../test/positive2.tf | 10 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 53 ++++++++ .../metadata.json | 13 ++ .../query.rego | 76 +++++++++++ .../test/negative1.tf | 25 ++++ .../test/positive1.tf | 9 ++ .../test/positive2.tf | 24 ++++ .../test/positive3.tf | 26 ++++ .../test/positive_expected_result.json | 20 +++ .../README.md | 54 ++++++++ .../metadata.json | 13 ++ .../query.rego | 75 +++++++++++ .../test/negative1.tf | 24 ++++ .../test/positive1.tf | 9 ++ .../test/positive2.tf | 23 ++++ .../test/positive3.tf | 25 ++++ .../test/positive_expected_result.json | 20 +++ .../README.md | 40 ++++++ .../metadata.json | 13 ++ .../query.rego | 29 +++++ .../test/negative1.tf | 13 ++ .../test/negative2.tf | 13 ++ .../test/positive1.tf | 13 ++ .../test/positive2.tf | 13 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 40 ++++++ .../metadata.json | 13 ++ .../query.rego | 44 +++++++ .../test/negative1.tf | 11 ++ .../test/negative2.tf | 11 ++ .../test/positive1.tf | 9 ++ .../test/positive2.tf | 11 ++ .../test/positive_expected_result.json | 14 ++ .../README.md | 56 ++++++++ .../metadata.json | 13 ++ .../query.rego | 73 +++++++++++ .../test/negative1.tf | 21 +++ .../test/positive1.tf | 6 + .../test/positive2.tf | 15 +++ .../test/positive3.tf | 15 +++ .../test/positive4.tf | 14 ++ .../test/positive_expected_result.json | 26 ++++ .../README.md | 54 ++++++++ .../metadata.json | 13 ++ .../query.rego | 75 +++++++++++ .../test/negative1.tf | 24 ++++ .../test/positive1.tf | 9 ++ .../test/positive2.tf | 23 ++++ .../test/positive3.tf | 25 ++++ .../test/positive_expected_result.json | 20 +++ 709 files changed, 15864 insertions(+) create mode 100644 assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/README.md create mode 100644 assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json create mode 100644 assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego create mode 100644 assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative2.tf create mode 100644 assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_app_service_http_logs_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_bastion_host_missing/README.md create mode 100644 assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json create mode 100644 assets/queries/terraform/azure/azure_bastion_host_missing/query.rego create mode 100644 assets/queries/terraform/azure/azure_bastion_host_missing/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_bastion_host_missing/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_bastion_host_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_defender_easm_enabled_manual/README.md create mode 100644 assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json create mode 100644 assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego create mode 100644 assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/README.md create mode 100644 assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_iot_hub_defender_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/README.md create mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json create mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego create mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/README.md create mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json create mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego create mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_paas_private_endpoint_missing/README.md create mode 100644 assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json create mode 100644 assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego create mode 100644 assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/README.md create mode 100644 assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json create mode 100644 assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego create mode 100644 assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/negative2.tf create mode 100644 assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/README.md create mode 100644 assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json create mode 100644 assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego create mode 100644 assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_storage_account_versioning_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_storage_blob_logging_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/README.md create mode 100644 assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json create mode 100644 assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego create mode 100644 assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/README.md create mode 100644 assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json create mode 100644 assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego create mode 100644 assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_storage_queue_logging_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/negative2.tf create mode 100644 assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive4.tf create mode 100644 assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/azure/azure_storage_table_logging_disabled/README.md create mode 100644 assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json create mode 100644 assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego create mode 100644 assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_access_approval_disabled/README.md create mode 100644 assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_access_approval_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/README.md create mode 100644 assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/README.md create mode 100644 assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/README.md create mode 100644 assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/README.md create mode 100644 assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_default_service_account_used/README.md create mode 100644 assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/README.md create mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative2.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_manual_iam_check/README.md create mode 100644 assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/README.md create mode 100644 assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/negative2.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive4.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/README.md create mode 100644 assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/negative2.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive4.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/README.md create mode 100644 assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/README.md create mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative2.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/README.md create mode 100644 assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/README.md create mode 100644 assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/README.md create mode 100644 assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/README.md create mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive_expected_result.json create mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/README.md create mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json create mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego create mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/negative1.tf create mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive1.tf create mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive2.tf create mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/README.md create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/README.md create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/README.md create mode 100644 assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/README.md create mode 100644 assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/README.md create mode 100644 assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive2.tf create mode 100644 assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/README.md create mode 100644 assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive2.tf create mode 100644 assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/README.md create mode 100644 assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive2.tf create mode 100644 assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/README.md create mode 100644 assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/README.md create mode 100644 assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/README.md create mode 100644 assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/README.md create mode 100644 assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/README.md create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive2.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/README.md create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/README.md create mode 100644 assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive2.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/README.md create mode 100644 assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/README.md create mode 100644 assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/README.md create mode 100644 assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive2.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/README.md create mode 100644 assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive2.tf create mode 100644 assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/README.md create mode 100644 assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/README.md create mode 100644 assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/README.md create mode 100644 assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive2.tf create mode 100644 assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/README.md create mode 100644 assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/README.md create mode 100644 assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/ibm/ibm_logdna_view_without_alert/README.md create mode 100644 assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json create mode 100644 assets/queries/terraform/ibm/ibm_logdna_view_without_alert/query.rego create mode 100644 assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/negative1.tf create mode 100644 assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/positive1.tf create mode 100644 assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/README.md create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/query.rego create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/README.md create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/README.md create mode 100644 assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json create mode 100644 assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/query.rego create mode 100644 assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_compute_secure_boot_disabled/README.md create mode 100644 assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json create mode 100644 assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego create mode 100644 assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_default_tags_not_defined/README.md create mode 100644 assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json create mode 100644 assets/queries/terraform/oci/oci_default_tags_not_defined/query.rego create mode 100644 assets/queries/terraform/oci/oci_default_tags_not_defined/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_default_tags_not_defined/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_default_tags_not_defined/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/README.md create mode 100644 assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json create mode 100644 assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego create mode 100644 assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_iam_password_expiration_manual/README.md create mode 100644 assets/queries/terraform/oci/oci_iam_password_expiration_manual/metadata.json create mode 100644 assets/queries/terraform/oci/oci_iam_password_expiration_manual/query.rego create mode 100644 assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_iam_password_policy_length/README.md create mode 100644 assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json create mode 100644 assets/queries/terraform/oci/oci_iam_password_policy_length/query.rego create mode 100644 assets/queries/terraform/oci/oci_iam_password_policy_length/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_iam_password_reuse_manual/README.md create mode 100644 assets/queries/terraform/oci/oci_iam_password_reuse_manual/metadata.json create mode 100644 assets/queries/terraform/oci/oci_iam_password_reuse_manual/query.rego create mode 100644 assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/README.md create mode 100644 assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json create mode 100644 assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego create mode 100644 assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_iam_service_admins_manual/README.md create mode 100644 assets/queries/terraform/oci/oci_iam_service_admins_manual/metadata.json create mode 100644 assets/queries/terraform/oci/oci_iam_service_admins_manual/query.rego create mode 100644 assets/queries/terraform/oci/oci_iam_service_admins_manual/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_iam_service_admins_manual/test/negative2.tf create mode 100644 assets/queries/terraform/oci/oci_iam_service_admins_manual/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_iam_service_admins_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/README.md create mode 100644 assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json create mode 100644 assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego create mode 100644 assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_idp_change_event_rule_missing/README.md create mode 100644 assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json create mode 100644 assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego create mode 100644 assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/README.md create mode 100644 assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json create mode 100644 assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego create mode 100644 assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_instance_transit_encryption/README.md create mode 100644 assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json create mode 100644 assets/queries/terraform/oci/oci_instance_transit_encryption/query.rego create mode 100644 assets/queries/terraform/oci/oci_instance_transit_encryption/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/README.md create mode 100644 assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json create mode 100644 assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego create mode 100644 assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/README.md create mode 100644 assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json create mode 100644 assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego create mode 100644 assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_notification_topic_without_subscription/README.md create mode 100644 assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json create mode 100644 assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego create mode 100644 assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/README.md create mode 100644 assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json create mode 100644 assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego create mode 100644 assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/README.md create mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json create mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/query.rego create mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/README.md create mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json create mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/query.rego create mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_resource_created_in_root_compartment/README.md create mode 100644 assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json create mode 100644 assets/queries/terraform/oci/oci_resource_created_in_root_compartment/query.rego create mode 100644 assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/README.md create mode 100644 assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json create mode 100644 assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego create mode 100644 assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/README.md create mode 100644 assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json create mode 100644 assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego create mode 100644 assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/README.md create mode 100644 assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/metadata.json create mode 100644 assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/query.rego create mode 100644 assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative2.tf create mode 100644 assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/README.md create mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json create mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/query.rego create mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative2.tf create mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/README.md create mode 100644 assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json create mode 100644 assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/query.rego create mode 100644 assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive4.tf create mode 100644 assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive_expected_result.json create mode 100644 assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/README.md create mode 100644 assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json create mode 100644 assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego create mode 100644 assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/negative1.tf create mode 100644 assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive1.tf create mode 100644 assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive2.tf create mode 100644 assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive3.tf create mode 100644 assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive_expected_result.json diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/README.md b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/README.md new file mode 100644 index 00000000000..151365fca5b --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/README.md @@ -0,0 +1,46 @@ +# Regla KICS: App Service Application Insights Not Configured + +## Descripción General + +Esta regla verifica que los servicios de Azure App Service y Function Apps tengan configurada la integración con **Application Insights**. + +Application Insights es una característica de Azure Monitor que proporciona gestión del rendimiento de aplicaciones (APM) y seguimiento de errores en tiempo real. Para vincular un App Service con Application Insights en Terraform, se debe definir `APPLICATIONINSIGHTS_CONNECTION_STRING` (recomendado) o `APPINSIGHTS_INSTRUMENTATIONKEY` dentro del bloque `app_settings`. + +## Lógica de la Regla + +La política itera sobre los recursos `azurerm_linux_web_app`, `azurerm_windows_web_app`, `azurerm_linux_function_app` y `azurerm_windows_function_app`. +Verifica la configuración en dos niveles: +1. **Ausencia de app_settings:** Si el bloque no está definido. +2. **Configuración incompleta:** Si el bloque existe pero no contiene las claves de conexión. + +## Casos de Fallo Detectados + +### Caso 1: Falta Configuración en app_settings + +* **Descripción:** El recurso no tiene el bloque `app_settings` definido. +* **Ubicación de la Alerta:** Nivel de recurso principal. + +### Caso 2: Claves de App Insights ausentes + +* **Descripción:** El bloque `app_settings` existe pero no contiene `APPLICATIONINSIGHTS_CONNECTION_STRING` ni `APPINSIGHTS_INSTRUMENTATIONKEY`. +* **Ubicación de la Alerta:** Atributo `app_settings`. + +## Recurso Involucrado + +* `azurerm_linux_web_app` +* `azurerm_windows_web_app` +* `azurerm_linux_function_app` +* `azurerm_windows_function_app` + +## Solución + +Defina `APPLICATIONINSIGHTS_CONNECTION_STRING` dentro de los `app_settings`. + +```terraform +resource "azurerm_linux_web_app" "example" { + name = "example-app" + # ... + app_settings = { + "APPLICATIONINSIGHTS_CONNECTION_STRING" = azurerm_application_insights.example.connection_string + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json new file mode 100644 index 00000000000..72ff8d8cb65 --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "721c26ff-776f-4d7a-b151-45447712343b", + "queryName": "App Service Application Insights Not Configured", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that Azure App Services and Function Apps are linked to Application Insights for performance monitoring and error tracking.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_web_app#app_settings", + "platform": "Terraform", + "descriptionID": "721c26ff", + "cloudProvider": "azure", + "cwe": "CWE-778", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego new file mode 100644 index 00000000000..52d2cefd933 --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego @@ -0,0 +1,44 @@ +package Cx + +targets := { + "azurerm_linux_web_app", + "azurerm_windows_web_app", + "azurerm_linux_function_app", + "azurerm_windows_function_app" +} + +# REGLA 1: El bloque 'app_settings' no existe en absoluto. +CxPolicy[result] { + doc := input.document[i] + resource_type := targets[t] + app := doc.resource[resource_type][name] + + not app.app_settings + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.%s.%s", [resource_type, name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'%s.%s' should have 'app_settings' defined", [resource_type, name]), + "keyActualValue": sprintf("'%s.%s' is missing 'app_settings'", [resource_type, name]), + } +} + +# REGLA 2: El bloque 'app_settings' existe pero no tiene ninguna clave de App Insights. +CxPolicy[result] { + doc := input.document[i] + resource_type := targets[t] + app := doc.resource[resource_type][name] + + app.app_settings + not app.app_settings["APPLICATIONINSIGHTS_CONNECTION_STRING"] + not app.app_settings["APPINSIGHTS_INSTRUMENTATIONKEY"] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.%s.%s.app_settings", [resource_type, name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'app_settings' should contain 'APPLICATIONINSIGHTS_CONNECTION_STRING'", + "keyActualValue": "'app_settings' does not contain Application Insights configuration", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative1.tf b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative1.tf new file mode 100644 index 00000000000..a37f36b739b --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative1.tf @@ -0,0 +1,11 @@ +# Caso con Connection String (Recomendado) +resource "azurerm_linux_web_app" "pass_connection_string" { + name = "pass-app-1" + resource_group_name = "rg" + location = "West Europe" + service_plan_id = "plan-id" + + app_settings = { + "APPLICATIONINSIGHTS_CONNECTION_STRING" = "InstrumentationKey=0000;IngestionEndpoint=https://..." + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative2.tf b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative2.tf new file mode 100644 index 00000000000..143f597f488 --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative2.tf @@ -0,0 +1,11 @@ +# Caso con Instrumentation Key (Legacy) +resource "azurerm_windows_web_app" "pass_instrumentation_key" { + name = "pass-app-2" + resource_group_name = "rg" + location = "West Europe" + service_plan_id = "plan-id" + + app_settings = { + "APPINSIGHTS_INSTRUMENTATIONKEY" = "0000-0000-0000-0000" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive1.tf b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive1.tf new file mode 100644 index 00000000000..f44da5b65d5 --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive1.tf @@ -0,0 +1,6 @@ +resource "azurerm_linux_web_app" "fail_no_settings" { + name = "fail-app-no-settings" + resource_group_name = "rg" + location = "West Europe" + service_plan_id = "plan-id" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive2.tf b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive2.tf new file mode 100644 index 00000000000..7ed5d045e78 --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive2.tf @@ -0,0 +1,10 @@ +resource "azurerm_windows_web_app" "fail_incomplete_settings" { + name = "fail-app-incomplete" + resource_group_name = "rg" + location = "West Europe" + service_plan_id = "plan-id" + + app_settings = { + "WEBSITE_NODE_DEFAULT_VERSION" = "14.15.0" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive_expected_result.json new file mode 100644 index 00000000000..42119a5fba2 --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "App Service Application Insights Not Configured", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "App Service Application Insights Not Configured", + "severity": "MEDIUM", + "line": 7, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/README.md b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/README.md new file mode 100644 index 00000000000..9ee37293f24 --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/README.md @@ -0,0 +1,55 @@ +# Regla KICS: App Service HTTP Logs Disabled + +## Descripción General + +Esta regla verifica que los servicios de Azure App Service (`azurerm_linux_web_app` y `azurerm_windows_web_app`) tengan habilitados los logs HTTP. + +Los logs de HTTP registran las solicitudes web que recibe la aplicación, incluyendo la URL solicitada, el agente de usuario, la dirección IP del cliente y el código de estado de la respuesta. Esta información es fundamental para la auditoría de seguridad, el cumplimiento normativo y la resolución de problemas de tráfico. + +## Lógica de la Regla + +La política itera sobre los recursos de App Service y verifica la configuración en dos pasos: +1. **Ausencia de Logs:** Verifica si el bloque `logs` existe. +2. **Ausencia de Logs HTTP:** Si el bloque `logs` existe, verifica que contenga el sub-bloque `http_logs`. + +Si el logging HTTP no está explícitamente habilitado, se genera una alerta. + +## Casos de Fallo Detectados + +### Caso 1: Configuración de Logs Ausente + +* **Descripción:** El recurso App Service se define sin especificar ninguna configuración de `logs`. +* **Ubicación de la Alerta:** Nivel de recurso principal. + +### Caso 2: Bloque http_logs Omitido + +* **Descripción:** Se define el bloque `logs` (por ejemplo, para logs de aplicación), pero se omiten los logs de tráfico HTTP. +* **Ubicación de la Alerta:** Bloque `logs`. + +## Recurso Involucrado + +* `azurerm_linux_web_app` +* `azurerm_windows_web_app` + +## Solución + +Añada el bloque `logs` y configure `http_logs` definiendo un sistema de archivos (`file_system`) o un almacenamiento de blobs (`azure_blob_storage`). + +```terraform +resource "azurerm_linux_web_app" "example_secure" { + name = "example-linux-web-app-secure" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + service_plan_id = azurerm_service_plan.example.id + + site_config {} + + logs { + http_logs { + file_system { + retention_in_days = 7 + retention_in_mb = 35 + } + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json new file mode 100644 index 00000000000..b30be71a396 --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "72eb3dd8-6892-47d1-9965-a5682de9f4e7", + "queryName": "App Service HTTP Logs Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that HTTP logs are enabled for Azure App Services. HTTP logs provide records of HTTP requests to the web app, which are crucial for security monitoring and debugging.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_web_app#http_logs", + "platform": "Terraform", + "descriptionID": "72eb3dd8", + "cloudProvider": "azure", + "cwe": "CWE-778", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego new file mode 100644 index 00000000000..8ed6d368b34 --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego @@ -0,0 +1,38 @@ +package Cx + +targets := {"azurerm_linux_web_app", "azurerm_windows_web_app"} + +# REGLA 1: El bloque 'logs' no existe en el App Service. +CxPolicy[result] { + doc := input.document[i] + resource_type := targets[t] + app := doc.resource[resource_type][name] + + not app.logs + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.%s.%s", [resource_type, name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'%s.%s' should have a 'logs' block defined", [resource_type, name]), + "keyActualValue": sprintf("'%s.%s' is missing the 'logs' block", [resource_type, name]), + } +} + +# REGLA 2: El bloque 'logs' existe pero no tiene 'http_logs' configurado. +CxPolicy[result] { + doc := input.document[i] + resource_type := targets[t] + app := doc.resource[resource_type][name] + + app.logs + not app.logs.http_logs + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.%s.%s.logs", [resource_type, name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'%s.%s.logs' should have 'http_logs' configured", [resource_type, name]), + "keyActualValue": sprintf("'%s.%s.logs' is missing 'http_logs'", [resource_type, name]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/negative1.tf new file mode 100644 index 00000000000..5b6ce2ddf69 --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/negative1.tf @@ -0,0 +1,15 @@ +resource "azurerm_linux_web_app" "pass_app" { + name = "app-pass" + resource_group_name = "rg" + location = "West Europe" + service_plan_id = "plan-id" + + logs { + http_logs { + file_system { + retention_in_days = 7 + retention_in_mb = 35 + } + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive1.tf new file mode 100644 index 00000000000..e797b245c24 --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive1.tf @@ -0,0 +1,8 @@ +resource "azurerm_linux_web_app" "fail_no_logs" { + name = "app-fail-1" + resource_group_name = "rg" + location = "West Europe" + service_plan_id = "plan-id" + + site_config {} +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive2.tf new file mode 100644 index 00000000000..6078908f9d1 --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive2.tf @@ -0,0 +1,13 @@ +resource "azurerm_windows_web_app" "fail_incomplete_logs" { + name = "app-fail-2" + resource_group_name = "rg" + location = "West Europe" + service_plan_id = "plan-id" + + logs { + application_logs { + file_system_level = "Information" + } + # Falta http_logs + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..2b9ba210834 --- /dev/null +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "App Service HTTP Logs Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "App Service HTTP Logs Disabled", + "severity": "MEDIUM", + "line": 7, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/README.md new file mode 100644 index 00000000000..deb4f3433de --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/README.md @@ -0,0 +1,37 @@ +# Regla KICS: Backup Vault CMK Encryption Disabled + +## Descripción General + +Esta regla verifica que los almacenes de copias de seguridad de Azure (**Backup Vaults** del servicio Data Protection) estén cifrados utilizando **Customer-Managed Keys (CMK)**. + +El uso de claves gestionadas por el cliente proporciona un control total sobre el ciclo de vida de las claves (creación, rotación y revocación) y es un requisito común en entornos con altas exigencias de seguridad y cumplimiento. En Terraform, esto se configura mediante un recurso separado (`azurerm_data_protection_backup_vault_customer_managed_key`) que vincula el Vault con la clave almacenada en un Key Vault. + +## Lógica de la Regla + +La política realiza un análisis de relaciones entre recursos: +1. Identifica todos los recursos `azurerm_data_protection_backup_vault`. +2. Busca si existe un recurso `azurerm_data_protection_backup_vault_customer_managed_key` cuya propiedad `data_protection_backup_vault_id` apunte al Vault analizado. +3. Verifica que dicho recurso de asociación tenga definido el atributo `key_vault_key_id`. +4. Si no existe esta vinculación, se genera una alerta indicando que el Vault usa claves gestionadas por la plataforma (configuración por defecto). + +## Casos de Fallo Detectados + +### Caso 1: Backup Vault sin CMK + +* **Descripción:** Se define el Backup Vault pero no se encuentra el recurso de asociación de la clave de cifrado gestionada por el cliente. +* **Ubicación de la Alerta:** Sobre el recurso `azurerm_data_protection_backup_vault`. + +## Recurso Involucrado + +* `azurerm_data_protection_backup_vault` +* `azurerm_data_protection_backup_vault_customer_managed_key` + +## Solución + +Define el recurso de asociación `azurerm_data_protection_backup_vault_customer_managed_key` y vincúlalo al Vault y a la Key correspondiente. + +```terraform +resource "azurerm_data_protection_backup_vault_customer_managed_key" "example" { + data_protection_backup_vault_id = azurerm_data_protection_backup_vault.example.id + key_vault_key_id = azurerm_key_vault_key.example.id +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json new file mode 100644 index 00000000000..4b63512897a --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "bf4474a7-7495-4292-af22-a97c1cc95d2b", + "queryName": "Backup Vault CMK Encryption Disabled", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that Azure Backup Vaults (Data Protection) are encrypted using Customer-Managed Keys (CMK) stored in Azure Key Vault, instead of platform-managed keys.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/data_protection_backup_vault_customer_managed_key", + "platform": "Terraform", + "descriptionID": "bf4474a7", + "cloudProvider": "azure", + "cwe": "CWE-326", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego new file mode 100644 index 00000000000..114fb74bd78 --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego @@ -0,0 +1,25 @@ +package Cx + +has_cmk_configured(doc, vault_id) { + cmk := doc.resource.azurerm_data_protection_backup_vault_customer_managed_key[_] + cmk.data_protection_backup_vault_id == vault_id + cmk.key_vault_key_id +} + +# REGLA 1: El Backup Vault no tiene cifrado CMK configurado a través del recurso de asociación. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_data_protection_backup_vault[name] + + vault_id := sprintf("${azurerm_data_protection_backup_vault.%s.id}", [name]) + + not has_cmk_configured(doc, vault_id) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_data_protection_backup_vault.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should be associated with an 'azurerm_data_protection_backup_vault_customer_managed_key' resource", [name]), + "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is using Platform-Managed Keys (default)", [name]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/negative1.tf new file mode 100644 index 00000000000..8c6778ce2a1 --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/negative1.tf @@ -0,0 +1,16 @@ +resource "azurerm_data_protection_backup_vault" "pass_vault" { + name = "backup-vault-secure" + resource_group_name = "rg-backup" + location = "East US" + datastore_type = "VaultStore" + redundancy = "LocallyRedundant" + + identity { + type = "SystemAssigned" + } +} + +resource "azurerm_data_protection_backup_vault_customer_managed_key" "pass_cmk" { + data_protection_backup_vault_id = azurerm_data_protection_backup_vault.pass_vault.id + key_vault_key_id = "https://example-kv.vault.azure.net/keys/example-key/version" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive1.tf new file mode 100644 index 00000000000..d9b59238be8 --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive1.tf @@ -0,0 +1,11 @@ +resource "azurerm_data_protection_backup_vault" "fail_vault" { + name = "backup-vault-insecure" + resource_group_name = "rg-backup" + location = "East US" + datastore_type = "VaultStore" + redundancy = "LocallyRedundant" + + identity { + type = "SystemAssigned" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..6ef8a5a5a91 --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "Backup Vault CMK Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/README.md b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/README.md new file mode 100644 index 00000000000..14f5f15e08b --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/README.md @@ -0,0 +1,47 @@ +# Regla KICS: Backup Vault Cross Region Restore Disabled + +## Descripción General + +Esta regla verifica que la funcionalidad de **Restauración entre Regiones** (`cross_region_restore_enabled`) esté habilitada en los recursos `azurerm_data_protection_backup_vault`. + +Cross Region Restore (CRR) permite restaurar los datos de copia de seguridad en una región secundaria de Azure emparejada (Azure Paired Region). Esto es fundamental para garantizar la continuidad del negocio y la recuperación de datos en caso de que la región principal sufra una interrupción total o un desastre geográfico. + +**Nota:** Para utilizar CRR de manera efectiva, el almacén requiere que la redundancia esté configurada como `GeoRedundant`. + +## Lógica de la Regla + +La política evalúa el recurso `azurerm_data_protection_backup_vault` bajo dos escenarios: +1. **Atributo Ausente:** Si no se define explícitamente `cross_region_restore_enabled`, se genera una alerta sobre el recurso (ya que el valor por defecto en la plataforma suele ser false). +2. **Deshabilitado Explícitamente:** Si el atributo se establece como `false`, la alerta apunta directamente a la línea de la configuración incorrecta. + +## Casos de Fallo Detectados + +--- + +### Caso 1: Configuración Ausente +* **Descripción:** Se define el Backup Vault sin especificar la política de restauración entre regiones, dejando los datos vulnerables a fallos regionales. +* **Ubicación de la Alerta:** Nivel de recurso `azurerm_data_protection_backup_vault`. + +### Caso 2: CRR Deshabilitado +* **Descripción:** El atributo `cross_region_restore_enabled` está configurado explícitamente como `false`. +* **Ubicación de la Alerta:** Línea `cross_region_restore_enabled`. + +## Recurso Involucrado + +* `azurerm_data_protection_backup_vault` + +## Solución + +Establezca el atributo `cross_region_restore_enabled` en `true`. Es altamente recomendable verificar que el tipo de redundancia (`redundancy`) esté configurado como `GeoRedundant`. + +```terraform +resource "azurerm_data_protection_backup_vault" "example_secure" { + name = "vault-secure" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + datastore_type = "VaultStore" + redundancy = "GeoRedundant" + + # Solución técnica + cross_region_restore_enabled = true +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json new file mode 100644 index 00000000000..5bb3f8ea098 --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "0117fb32-4265-444d-8030-a0a034958489", + "queryName": "Backup Vault Cross Region Restore Disabled", + "severity": "MEDIUM", + "category": "Backup", + "descriptionText": "Ensures that 'Cross Region Restore' is enabled for Azure Backup Vaults. This allows backup data to be restored in a secondary region, which is critical for disaster recovery scenarios.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/data_protection_backup_vault#cross_region_restore_enabled", + "platform": "Terraform", + "descriptionID": "0117fb32", + "cloudProvider": "azure", + "cwe": "CWE-668", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego new file mode 100644 index 00000000000..899dc447728 --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego @@ -0,0 +1,33 @@ +package Cx + +# REGLA 1: Configuración Ausente. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_data_protection_backup_vault[name] + + object.get(vault, "cross_region_restore_enabled", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_data_protection_backup_vault.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should have 'cross_region_restore_enabled' set to true", [name]), + "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is missing 'cross_region_restore_enabled'", [name]), + } +} + +# REGLA 2: Configuración Incorrecta (Deshabilitado explícitamente). +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_data_protection_backup_vault[name] + + vault.cross_region_restore_enabled == false + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_data_protection_backup_vault.%s.cross_region_restore_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'cross_region_restore_enabled' should be set to true", + "keyActualValue": "'cross_region_restore_enabled' is set to false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/negative1.tf new file mode 100644 index 00000000000..1897017fb9d --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/negative1.tf @@ -0,0 +1,9 @@ +resource "azurerm_data_protection_backup_vault" "pass" { + name = "vault-ok" + resource_group_name = "rg-test" + location = "West Europe" + datastore_type = "VaultStore" + redundancy = "GeoRedundant" + + cross_region_restore_enabled = true +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive1.tf new file mode 100644 index 00000000000..b59e9f3d5a6 --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive1.tf @@ -0,0 +1,8 @@ +resource "azurerm_data_protection_backup_vault" "fail_missing" { + name = "vault-missing-crr" + resource_group_name = "rg-test" + location = "West Europe" + datastore_type = "VaultStore" + redundancy = "GeoRedundant" + # FALLO: Falta cross_region_restore_enabled +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive2.tf new file mode 100644 index 00000000000..8a9cf10f0da --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive2.tf @@ -0,0 +1,9 @@ +resource "azurerm_data_protection_backup_vault" "fail_explicit" { + name = "vault-disabled-crr" + resource_group_name = "rg-test" + location = "West Europe" + datastore_type = "VaultStore" + redundancy = "GeoRedundant" + + cross_region_restore_enabled = false # FALLO +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..bcfd1994ee5 --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Backup Vault Cross Region Restore Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Backup Vault Cross Region Restore Disabled", + "severity": "MEDIUM", + "line": 8, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/README.md new file mode 100644 index 00000000000..9ca0aa51be4 --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/README.md @@ -0,0 +1,42 @@ +# Regla KICS: Backup Vault Infrastructure Encryption Disabled + +## Descripción General + +Esta regla verifica la preparación para el cifrado avanzado en los almacenes de respaldo de Azure (**Data Protection Backup Vaults**). + +Para que un Backup Vault pueda soportar capas de cifrado adicionales o gestionadas por el cliente (CMK), es obligatorio que el recurso tenga una identidad asignada (`identity`). Sin una identidad, el almacén solo puede utilizar el cifrado predeterminado de la plataforma. + +## Lógica de la Regla + +La política audita el recurso `azurerm_data_protection_backup_vault`: +1. Verifica la existencia del bloque `identity`. +2. Si el bloque está ausente, se considera que el recurso no está preparado para configuraciones de cifrado de infraestructura o gestionado por el cliente. + +## Casos de Fallo Detectados + +### Caso 1: Identidad no configurada + +* **Descripción:** El Backup Vault no tiene una identidad (SystemAssigned o UserAssigned), lo que impide la vinculación con claves de cifrado externas. +* **Ubicación de la Alerta:** Nivel de recurso `azurerm_data_protection_backup_vault`. + +## Recurso Involucrado + +* `azurerm_data_protection_backup_vault` + +## Solución + +Añada un bloque `identity` al recurso. + +```terraform +resource "azurerm_data_protection_backup_vault" "example" { + name = "vault-secure" + resource_group_name = "rg-example" + location = "West Europe" + datastore_type = "VaultStore" + redundancy = "LocallyRedundant" + + # Solución técnica para habilitar capacidades de cifrado + identity { + type = "SystemAssigned" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json new file mode 100644 index 00000000000..e766039db6a --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "f7bf03d5-ae0e-4b36-aab3-f8d2346a8843", + "queryName": "Backup Vault Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that 'Infrastructure Encryption' is enabled for Azure Backup Vaults. This provides a second layer of encryption (double encryption) for data at rest.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/data_protection_backup_vault#infrastructure_encryption_enabled", + "platform": "Terraform", + "descriptionID": "f7bf03d5", + "cloudProvider": "azure", + "cwe": "CWE-312", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego new file mode 100644 index 00000000000..42de971f8c9 --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego @@ -0,0 +1,17 @@ +package Cx + +# REGLA 1: Falta el bloque 'identity', necesario para gestionar cifrado avanzado. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_data_protection_backup_vault[name] + + not vault.identity + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_data_protection_backup_vault.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should have an 'identity' block to support advanced encryption", [name]), + "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is missing the 'identity' block", [name]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/negative1.tf new file mode 100644 index 00000000000..339fa323b7f --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/negative1.tf @@ -0,0 +1,11 @@ +resource "azurerm_data_protection_backup_vault" "pass" { + name = "vault-with-identity" + resource_group_name = "rg" + location = "West Europe" + datastore_type = "VaultStore" + redundancy = "LocallyRedundant" + + identity { + type = "SystemAssigned" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive1.tf new file mode 100644 index 00000000000..f058b9766a1 --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive1.tf @@ -0,0 +1,8 @@ +resource "azurerm_data_protection_backup_vault" "fail" { + name = "vault-no-identity" + resource_group_name = "rg" + location = "West Europe" + datastore_type = "VaultStore" + redundancy = "LocallyRedundant" + # FALLO: No tiene bloque identity +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..4979de3f2ab --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "Backup Vault Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/README.md b/assets/queries/terraform/azure/azure_bastion_host_missing/README.md new file mode 100644 index 00000000000..63ef51ce4f3 --- /dev/null +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/README.md @@ -0,0 +1,50 @@ +# Regla KICS: Azure Bastion Host Missing + +## Descripción General + +Esta regla verifica que, si se están desplegando redes virtuales (`azurerm_virtual_network`), exista al menos un recurso **Azure Bastion Host** (`azurerm_bastion_host`) definido en la configuración. + +Azure Bastion es un servicio PaaS que se aprovisiona dentro de una red virtual. Proporciona conectividad RDP y SSH segura directamente desde el portal de Azure a través de SSL. Esto elimina la necesidad de exponer puertos administrativos (22, 3389) a Internet o gestionar complejas VPNs y Jumpboxes para tareas de mantenimiento, reduciendo drásticamente la superficie de ataque. + +## Lógica de la Regla + +La política realiza un análisis de presencia de recursos a nivel de documento: +1. Verifica si existe algún recurso `azurerm_virtual_network`. +2. Si existen redes, busca si hay algún recurso `azurerm_bastion_host` definido en el mismo archivo/contexto. +3. Si existen redes pero no se encuentra ningún Bastion Host, se genera una alerta sobre la red virtual. + +## Casos de Fallo Detectados + +### Caso 1: VNet sin Bastion Host + +* **Descripción:** Se define infraestructura de red, pero no se incluye el servicio de Bastion, lo que sugiere que el acceso administrativo podría estar realizándose de forma insegura mediante IPs públicas directas o puertos abiertos en los grupos de seguridad (NSG). +* **Ubicación de la Alerta:** Sobre el recurso `azurerm_virtual_network`. + +## Recurso Involucrado + +* `azurerm_virtual_network` +* `azurerm_bastion_host` + +## Solución + +Para solucionar el problema, define un recurso `azurerm_bastion_host` y asegúrate de crear la subred obligatoria llamada `AzureBastionSubnet`. + +```terraform +resource "azurerm_subnet" "example_bastion" { + name = "AzureBastionSubnet" + resource_group_name = azurerm_resource_group.example.name + virtual_network_name = azurerm_virtual_network.example.name + address_prefixes = ["10.0.1.0/24"] +} + +resource "azurerm_bastion_host" "example" { + name = "production-bastion" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + ip_configuration { + name = "configuration" + subnet_id = azurerm_subnet.example_bastion.id + public_ip_address_id = azurerm_public_ip.example.id + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json b/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json new file mode 100644 index 00000000000..b21e74e168d --- /dev/null +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "a3e941c5-7708-40d1-943b-7093446ef5e6", + "queryName": "Azure Bastion Host Missing", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that an Azure Bastion Host is present when Virtual Networks are defined. Azure Bastion provides secure and seamless RDP/SSH connectivity to your virtual machines directly from the Azure portal over SSL.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/bastion_host", + "platform": "Terraform", + "descriptionID": "a3e941c5", + "cloudProvider": "azure", + "cwe": "CWE-284", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego b/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego new file mode 100644 index 00000000000..0f5dabba3ac --- /dev/null +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego @@ -0,0 +1,20 @@ +package Cx + +# REGLA 1: Existe una VNet, pero no existe ningún recurso azurerm_bastion_host en el documento. +CxPolicy[result] { + doc := input.document[i] + + vnet := doc.resource.azurerm_virtual_network[name] + + bastions := [b | b := doc.resource.azurerm_bastion_host[_]] + + count(bastions) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_virtual_network.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("An 'azurerm_bastion_host' resource should be defined to protect Virtual Network '%s'", [name]), + "keyActualValue": "No 'azurerm_bastion_host' resource was found in the configuration", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/test/negative1.tf b/assets/queries/terraform/azure/azure_bastion_host_missing/test/negative1.tf new file mode 100644 index 00000000000..88141688bb2 --- /dev/null +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/test/negative1.tf @@ -0,0 +1,18 @@ +resource "azurerm_virtual_network" "pass_vnet" { + name = "secure-network" + resource_group_name = "rg-test" + location = "West Europe" + address_space = ["10.0.0.0/16"] +} + +resource "azurerm_bastion_host" "pass_bastion" { + name = "bastion-host" + location = "West Europe" + resource_group_name = "rg-test" + + ip_configuration { + name = "config" + subnet_id = "dummy-id" + public_ip_address_id = "dummy-pip-id" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive1.tf b/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive1.tf new file mode 100644 index 00000000000..2c9968f79d6 --- /dev/null +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive1.tf @@ -0,0 +1,6 @@ +resource "azurerm_virtual_network" "fail_vnet" { + name = "vulnerable-network" + resource_group_name = "rg-test" + location = "West Europe" + address_space = ["10.0.0.0/16"] +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..865959bff36 --- /dev/null +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "Azure Bastion Host Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/README.md b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/README.md new file mode 100644 index 00000000000..c4411fe5e3f --- /dev/null +++ b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/README.md @@ -0,0 +1,36 @@ +# Regla KICS: Microsoft Defender EASM Enabled (Manual) + +## Descripción General + +Esta regla funciona como un **recordatorio de cumplimiento manual**. Su objetivo es asegurar que se haya habilitado **Microsoft Defender External Attack Surface Monitoring (EASM)** para monitorear la exposición de los activos de Azure a Internet. + +EASM realiza un descubrimiento continuo de tus activos digitales (direcciones IP, dominios, certificados SSL, etc.) para identificar vulnerabilidades y riesgos en la "sombra" (Shadow IT). Dado que el proveedor actual de Terraform para Azure no cuenta con recursos nativos para gestionar este servicio, la verificación debe realizarse directamente en la plataforma. + +## Lógica de la Regla + +Debido a las limitaciones del análisis estático para este servicio específico: +1. La regla identifica la presencia de recursos `azurerm_resource_group`. +2. Genera una alerta de severidad **INFO** por cada grupo detectado. +3. Actúa como un check-list para que el equipo de seguridad valide el estado del servicio en el Portal de Azure. + +## Casos de Fallo Detectados + +### Caso 1: Verificación Manual Requerida + +* **Descripción:** Se ha detectado infraestructura desplegada, pero el estado de protección de EASM no es visible para KICS. +* **Ubicación de la Alerta:** Sobre el recurso `azurerm_resource_group`. + +## Recurso Involucrado + +* `azurerm_resource_group` + +## Solución + +Esta alerta no se resuelve mediante cambios en el código HCL estándar. + +**Pasos de remediación manual:** +1. Acceda al [Portal de Azure](https://portal.azure.com). +2. En el buscador superior, escriba **"Microsoft Defender EASM"**. +3. Verifique si existe un recurso EASM configurado y realizando escaneos activos. +4. Si no existe, considere su creación para mejorar la postura de seguridad externa. +5. Documente la verificación para cerrar el hallazgo en el reporte de KICS. \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json new file mode 100644 index 00000000000..9f1fe2d2c5a --- /dev/null +++ b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "b9f8511b-bd48-4e9d-8439-94e49e671490", + "queryName": "Microsoft Defender EASM Enabled (Manual)", + "severity": "INFO", + "category": "Observability", + "descriptionText": "Ensures that Microsoft Defender External Attack Surface Monitoring (EASM) is enabled. Since EASM cannot be fully configured or verified via standard Terraform resources yet, this rule serves as a manual reminder to verify the service in the Azure Portal.", + "descriptionUrl": "https://azure.microsoft.com/en-us/products/defender-easm/", + "platform": "Terraform", + "descriptionID": "b9f8511b", + "cloudProvider": "azure", + "cwe": "CWE-778", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego new file mode 100644 index 00000000000..b0084fd4d98 --- /dev/null +++ b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego @@ -0,0 +1,15 @@ +package Cx + +# REGLA 1: Genera un aviso manual por cada Resource Group encontrado. +CxPolicy[result] { + doc := input.document[i] + rg := doc.resource.azurerm_resource_group[name] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_resource_group.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("Microsoft Defender EASM should be verified manually for resource group '%s'", [name]), + "keyActualValue": "EASM status cannot be verified statically via Terraform (Manual Verification Required)", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive1.tf b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive1.tf new file mode 100644 index 00000000000..dd2fcad1cd6 --- /dev/null +++ b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive1.tf @@ -0,0 +1,4 @@ +resource "azurerm_resource_group" "audit_me" { + name = "rg-production-safety" + location = "East US" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..ccef5c4313c --- /dev/null +++ b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "Microsoft Defender EASM Enabled (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/README.md b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/README.md new file mode 100644 index 00000000000..fc1bb17ee44 --- /dev/null +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/README.md @@ -0,0 +1,52 @@ +# Regla KICS: Elastic SAN Public Network Access Enabled + +## Descripción General + +Esta regla de KICS verifica que los grupos de volúmenes de Azure Elastic SAN (`azurerm_elastic_san_volume_group`) tengan restringido el acceso desde redes públicas. + +En la arquitectura de Azure Elastic SAN, la seguridad y el aislamiento de red no se gestionan en el recurso raíz de la SAN, sino a nivel de **Volume Group**. Para garantizar que los volúmenes de datos no sean accesibles desde Internet, es imprescindible definir el bloque `network_rule`. La sola presencia de este bloque activa una política de denegación implícita para cualquier tráfico que no provenga de las subredes autorizadas, asegurando que la infraestructura solo sea accesible a través de la red privada. + +## Lógica de la Regla + +La política audita el recurso `azurerm_elastic_san_volume_group` analizando la siguiente condición: +1. **Existencia del Bloque de Red:** Se verifica la presencia del bloque `network_rule`. Si este bloque no está definido, el grupo de volúmenes carece de restricciones perimetrales, permitiendo potencialmente el acceso público. + +## Caso de Fallo Detectado + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso Único: Configuración de Red Ausente + +* **Descripción:** El grupo de volúmenes se define sin el bloque `network_rule`, lo que significa que no se están aplicando reglas de filtrado de IP o de red virtual para proteger los datos. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_elastic_san_volume_group" "example_insecure" { + name = "insecure-vg" + elastic_san_id = azurerm_elastic_san.example.id + + # El recurso carece del bloque network_rule, + # quedando expuesto a redes públicas. + } + ``` +* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_elastic_san_volume_group`. + +## Recurso Involucrado + +* `azurerm_elastic_san_volume_group` + +## Solución + +Para solucionar este riesgo de seguridad, defina el bloque `network_rule` vinculándolo a una subred autorizada mediante el atributo `subnet_id`. + +```terraform +resource "azurerm_elastic_san_volume_group" "secure_vg" { + name = "secure-volume-group" + elastic_san_id = azurerm_elastic_san.example.id + + # SOLUCIÓN: Definir reglas de red para denegar el acceso público + network_rule { + subnet_id = azurerm_subnet.example.id + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json new file mode 100644 index 00000000000..9bf0857c145 --- /dev/null +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "660863a5-bb45-4907-8afe-d7478177a446", + "queryName": "Elastic SAN Public Network Access Enabled", + "severity": "HIGH", + "category": "Networking and Firewall", + "descriptionText": "Ensures that 'public_network_access_enabled' is set to false for Azure Elastic SAN. Disabling public access ensures that the SAN is only accessible via private endpoints within the virtual network.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/elastic_san#public_network_access_enabled", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-284", + "descriptionID": "660863a5", + "riskScore": 9.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego new file mode 100644 index 00000000000..ab3e86102fe --- /dev/null +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego @@ -0,0 +1,18 @@ +package Cx + +# REGLA 1: El bloque 'network_rule' no está definido. +# En azurerm_elastic_san_volume_group, la ausencia del bloque permite el acceso público. +CxPolicy[result] { + doc := input.document[i] + vg := doc.resource.azurerm_elastic_san_volume_group[name] + + not vg.network_rule + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_elastic_san_volume_group.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_elastic_san_volume_group.%s' should have a 'network_rule' block to restrict public access", [name]), + "keyActualValue": sprintf("'azurerm_elastic_san_volume_group.%s' is missing the 'network_rule' block", [name]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/negative1.tf b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/negative1.tf new file mode 100644 index 00000000000..b2d4f4b0b26 --- /dev/null +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/negative1.tf @@ -0,0 +1,8 @@ +resource "azurerm_elastic_san_volume_group" "pass" { + name = "secure-vg" + elastic_san_id = "san-id" + + network_rule { + subnet_id = "/subscriptions/0000/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/s1" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive1.tf b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive1.tf new file mode 100644 index 00000000000..f03f3c5de58 --- /dev/null +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive1.tf @@ -0,0 +1,5 @@ +resource "azurerm_elastic_san_volume_group" "fail" { + name = "insecure-vg" + elastic_san_id = "san-id" + # Falla por no tener network_rule +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive_expected_result.json new file mode 100644 index 00000000000..dbe5fa31bfe --- /dev/null +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "Elastic SAN Public Network Access Enabled", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/README.md new file mode 100644 index 00000000000..fc8dfbdb8da --- /dev/null +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/README.md @@ -0,0 +1,68 @@ +# Regla KICS: Elastic SAN Volume Group CMK Encryption Disabled + +## Descripción General + +Esta regla de KICS verifica que los grupos de volúmenes de Azure Elastic SAN (`azurerm_elastic_san_volume_group`) estén configurados para utilizar claves gestionadas por el cliente (Customer-Managed Keys - CMK) para el cifrado de datos en reposo. + +El uso de CMK sobre las claves gestionadas por la plataforma por defecto es una práctica de seguridad crítica. Proporciona a las organizaciones un control total sobre el ciclo de vida de las claves criptográficas, incluyendo políticas de acceso, rotación y revocación. Esto es esencial para cumplir con requisitos regulatorios y garantizar que el acceso a los datos almacenados en la SAN esté protegido por claves bajo el control directo del cliente. + +## Lógica de la Regla + +La política analiza el recurso `azurerm_elastic_san_volume_group` validando dos pilares fundamentales: +1. **Configuración del Tipo:** El atributo `encryption_type` debe estar establecido inequívocamente como `EncryptionAtRestWithCustomerManagedKey`. +2. **Infraestructura de Soporte:** Si se selecciona CMK, el recurso debe incluir obligatoriamente los bloques `encryption` (que vincula la clave) e `identity` (que permite el acceso a la misma). + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- +### Caso 1: Cifrado CMK no Configurado (Uso de Claves de Plataforma) + +* **Descripción:** El recurso carece del atributo de cifrado CMK o utiliza el valor por defecto gestionado por la plataforma. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_elastic_san_volume_group" "fail_platform" { + name = "example-vg" + elastic_san_id = azurerm_elastic_san.example.id + } + ``` +* **Ubicación de la Alerta:** Recurso raíz `azurerm_elastic_san_volume_group`. + +--- +### Caso 2: CMK Seleccionado con Bloques Técnicos Ausentes + +* **Descripción:** Se ha activado el tipo de cifrado CMK, pero falta uno o ambos bloques (`encryption` / `identity`) necesarios para que el cifrado sea operativo. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_elastic_san_volume_group" "fail_missing_blocks" { + encryption_type = "EncryptionAtRestWithCustomerManagedKey" + # Falta bloque encryption o bloque identity + } + ``` +* **Ubicación de la Alerta:** Recurso raíz `azurerm_elastic_san_volume_group`. + +## Recurso Involucrado + +* `azurerm_elastic_san_volume_group` + +## Solución + +Para solucionar el problema, asegúrese de declarar el tipo de cifrado CMK e incluir los bloques técnicos requeridos con sus parámetros obligatorios. + +```terraform +resource "azurerm_elastic_san_volume_group" "secure_vg" { + name = "secure-volume-group" + elastic_san_id = azurerm_elastic_san.example.id + + encryption_type = "EncryptionAtRestWithCustomerManagedKey" + + encryption { + key_vault_key_id = azurerm_key_vault_key.example.id + } + + identity { + type = "UserAssigned" + identity_ids = [azurerm_user_assigned_identity.example.id] + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json new file mode 100644 index 00000000000..0da8c3ce89b --- /dev/null +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "3b101ad5-3602-4a9e-b6ca-16b7b31b153c", + "queryName": "Elastic SAN Volume Group CMK Encryption Disabled", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that Azure Elastic SAN Volume Groups are encrypted using Customer-Managed Keys (CMK). Using CMK provides control over key lifecycle and access policies, unlike the default platform-managed keys.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/elastic_san_volume_group#encryption_type", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-326", + "descriptionID": "3b101ad5", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego new file mode 100644 index 00000000000..9cee7397bb0 --- /dev/null +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego @@ -0,0 +1,38 @@ +package Cx + +# REGLA 1: El tipo de cifrado no es CMK o no está definido. +CxPolicy[result] { + doc := input.document[i] + vg := doc.resource.azurerm_elastic_san_volume_group[name] + + object.get(vg, "encryption_type", "undefined") != "EncryptionAtRestWithCustomerManagedKey" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_elastic_san_volume_group.%s", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'encryption_type' should be set to 'EncryptionAtRestWithCustomerManagedKey'", + "keyActualValue": sprintf("'encryption_type' is set to '%v'", [object.get(vg, "encryption_type", "PlatformKey (Default)")]), + } +} + +# REGLA 2: Si el tipo es CMK, debe existir tanto el bloque 'encryption' como el bloque 'identity'. +CxPolicy[result] { + doc := input.document[i] + vg := doc.resource.azurerm_elastic_san_volume_group[name] + vg.encryption_type == "EncryptionAtRestWithCustomerManagedKey" + + required_blocks := {"encryption", "identity"} + existing_blocks := {b | vg[b]} + missing := required_blocks - existing_blocks + + count(missing) > 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_elastic_san_volume_group.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_elastic_san_volume_group.%s' should have both 'encryption' and 'identity' blocks for CMK", [name]), + "keyActualValue": sprintf("'azurerm_elastic_san_volume_group.%s' is missing the following block(s): %s", [name, concat(", ", missing)]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/negative1.tf new file mode 100644 index 00000000000..b7475da1de0 --- /dev/null +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/negative1.tf @@ -0,0 +1,14 @@ +resource "azurerm_elastic_san_volume_group" "pass" { + name = "secure-vg" + elastic_san_id = "san-id" + encryption_type = "EncryptionAtRestWithCustomerManagedKey" + + encryption { + key_vault_key_id = "https://kv.vault.azure.net/keys/key/v1" + } + + identity { + type = "UserAssigned" + identity_ids = ["managed_id"] + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive1.tf new file mode 100644 index 00000000000..a3a7012a077 --- /dev/null +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive1.tf @@ -0,0 +1,5 @@ +resource "azurerm_elastic_san_volume_group" "fail_type" { + name = "vg-fail-type" + elastic_san_id = "san-id" + # Falla por no tener encryption_type CMK +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive2.tf new file mode 100644 index 00000000000..8eb87a597a9 --- /dev/null +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive2.tf @@ -0,0 +1,6 @@ +resource "azurerm_elastic_san_volume_group" "fail_blocks" { + name = "vg-fail-blocks" + elastic_san_id = "san-id" + encryption_type = "EncryptionAtRestWithCustomerManagedKey" + # Falla por faltar bloques encryption e identity +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..c0f988b83b3 --- /dev/null +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Elastic SAN Volume Group CMK Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive.tf" + }, + { + "queryName": "Elastic SAN Volume Group CMK Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/README.md b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/README.md new file mode 100644 index 00000000000..c40af7851dc --- /dev/null +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/README.md @@ -0,0 +1,72 @@ +# Regla KICS: Azure IoT Hub Defender Disabled + +## Descripción General + +Esta regla de KICS verifica que los recursos **Azure IoT Hub** (`azurerm_iothub`) estén protegidos por **Microsoft Defender for IoT**. + +Microsoft Defender for IoT proporciona una capa esencial de seguridad para entornos de Internet de las cosas, ofreciendo detección de amenazas en tiempo real y gestión de la postura de seguridad. La falta de esta protección deja a los dispositivos IoT y a la infraestructura central del Hub vulnerables ante ataques dirigidos, movimientos laterales y exfiltración de datos. En Terraform, esta protección se habilita vinculando el IoT Hub con un recurso del tipo `azurerm_iot_security_solution`. + +## Lógica de la Regla + +La política analiza la configuración de Terraform realizando los siguientes pasos: +1. **Identificación de Hubs:** Selecciona todos los recursos de tipo `azurerm_iothub`. +2. **Verificación de Soluciones:** Busca recursos `azurerm_iot_security_solution` en el documento. +3. **Validación de Vinculación:** Comprueba si el identificador del Hub está presente en la lista `iothub_ids` de alguna solución de seguridad definida, contemplando formatos directos o interpolados. +4. **Generación de Alerta:** Si un Hub no está referenciado en ninguna solución, se genera un hallazgo de seguridad. + +## Caso de Fallo Detectado + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso Único: IoT Hub sin Defender asociado + +* **Descripción:** Se define un recurso `azurerm_iothub` pero no se encuentra ningún recurso `azurerm_iot_security_solution` que lo incluya en su lista de IDs protegidos. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_iothub" "fail_hub" { + name = "insecure-iothub" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + + sku { + name = "S1" + capacity = "1" + } + } + + # No existe azurerm_iot_security_solution que referencie a fail_hub + ``` +* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_iothub`. + +## Recurso Involucrado + +* `azurerm_iothub` +* `azurerm_iot_security_solution` + +## Solución + +Para solucionar este riesgo, asegúrese de definir un recurso `azurerm_iot_security_solution` e incluir el ID del IoT Hub en el atributo `iothub_ids`. + +```terraform +resource "azurerm_iothub" "example" { + name = "secure-iothub" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + + sku { + name = "S1" + capacity = "1" + } +} + +# SOLUCIÓN: Definir la solución de seguridad y vincular el Hub +resource "azurerm_iot_security_solution" "example" { + name = "iot-security-solution" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + display_name = "Iot Security Solution" + + iothub_ids = [azurerm_iothub.example.id] +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json new file mode 100644 index 00000000000..4c7522e2bb0 --- /dev/null +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "13be738b-78fb-4d0f-a5ed-13e0f36fd385", + "queryName": "Azure IoT Hub Defender Disabled", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that Microsoft Defender for IoT is enabled for Azure IoT Hubs. Defender for IoT provides threat detection and security posture management for IoT environments.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/iot_security_solution", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-693", + "descriptionID": "13be738b", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego new file mode 100644 index 00000000000..13c444b6108 --- /dev/null +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego @@ -0,0 +1,33 @@ +package Cx + +# REGLA 1: IoT Hub sin solución de seguridad (azurerm_iot_security_solution) asociada. +CxPolicy[result] { + doc := input.document[i] + iot_hub := doc.resource.azurerm_iothub[hub_name] + + hub_ref := sprintf("azurerm_iothub.%s.id", [hub_name]) + + solutions := [sol | + sol := doc.resource.azurerm_iot_security_solution[_] + current_hub_id := sol.iothub_ids[_] + check_hub_id(current_hub_id, hub_ref) + ] + + count(solutions) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_iothub.%s", [hub_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_iothub.%s' should be included in 'iothub_ids' of an 'azurerm_iot_security_solution'", [hub_name]), + "keyActualValue": sprintf("'azurerm_iothub.%s' is not associated with any 'azurerm_iot_security_solution'", [hub_name]), + } +} + +check_hub_id(current, target) { + current == target +} + +check_hub_id(current, target) { + current == sprintf("${%s}", [target]) +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/negative1.tf new file mode 100644 index 00000000000..f28ce4531df --- /dev/null +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/negative1.tf @@ -0,0 +1,18 @@ +resource "azurerm_iothub" "pass" { + name = "example-iothub-pass" + resource_group_name = "rg-test" + location = "West Europe" + + sku { + name = "S1" + capacity = "1" + } +} + +resource "azurerm_iot_security_solution" "pass" { + name = "example-security-solution" + resource_group_name = "rg-test" + location = "West Europe" + display_name = "Iot Security Solution" + iothub_ids = [azurerm_iothub.pass.id] +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive1.tf new file mode 100644 index 00000000000..d91f9e76260 --- /dev/null +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive1.tf @@ -0,0 +1,10 @@ +resource "azurerm_iothub" "fail" { + name = "example-iothub-fail" + resource_group_name = "rg-test" + location = "West Europe" + + sku { + name = "S1" + capacity = "1" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..64e4501aad7 --- /dev/null +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "Azure IoT Hub Defender Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/README.md b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/README.md new file mode 100644 index 00000000000..520e46cf594 --- /dev/null +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/README.md @@ -0,0 +1,64 @@ +# Regla KICS: Key Vault Key Rotation Disabled + +## Descripción General + +Esta regla de KICS verifica que las claves criptográficas almacenadas en Azure Key Vault (`azurerm_key_vault_key`) tengan configurada una política de rotación automática. + +La rotación automática de claves es una práctica de seguridad esencial que limita la cantidad de datos cifrados con una sola versión de clave y reduce significativamente el impacto en caso de que una clave se vea comprometida. Configurar una política de rotación asegura que las claves se renueven de forma proactiva sin intervención manual, garantizando la continuidad operativa y el cumplimiento de estándares de seguridad como PCI-DSS o HIPAA. + +## Lógica de la Regla + +La política analiza el recurso `azurerm_key_vault_key` realizando los siguientes pasos: +1. **Identificación de Claves:** Selecciona todos los recursos de tipo `azurerm_key_vault_key`. +2. **Verificación de Política:** Comprueba la existencia del bloque de configuración `rotation_policy`. +3. **Generación de Alerta:** Si el bloque está ausente, se considera que la clave no tiene una estrategia de rotación definida y se genera un hallazgo. + +## Caso de Fallo Detectado + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso Único: Clave sin política de rotación + +* **Descripción:** Se define una clave criptográfica en Key Vault pero se omite el bloque `rotation_policy`, dejando la responsabilidad de la rotación a procesos manuales o permitiendo que la clave permanezca indefinidamente. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_key_vault_key" "fail_key" { + name = "example-key" + key_vault_id = azurerm_key_vault.example.id + key_type = "RSA" + key_size = 2048 + key_opts = ["decrypt", "encrypt", "sign", "verify"] + + # El recurso carece de la configuración rotation_policy + } + ``` +* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_key_vault_key`. + +## Recurso Involucrado + +* `azurerm_key_vault_key` + +## Solución + +Para solucionar este riesgo, añada el bloque `rotation_policy` definiendo el tiempo de expiración y las reglas de rotación automática deseadas. + +```terraform +resource "azurerm_key_vault_key" "secure_key" { + name = "example-key" + key_vault_id = azurerm_key_vault.example.id + key_type = "RSA" + key_size = 2048 + key_opts = ["decrypt", "encrypt", "sign", "verify"] + + # SOLUCIÓN: Definir política de rotación automática + rotation_policy { + expire_after = "P90D" + notify_before_expiry = "P29D" + + automatic { + time_before_expiry = "P30D" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json new file mode 100644 index 00000000000..6498e1bff29 --- /dev/null +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "ca1ffce5-e2f9-4d8a-978e-719d1ed7c7fa", + "queryName": "Key Vault Key Rotation Disabled", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that cryptographic keys in Azure Key Vault have an automatic rotation policy configured. Regular key rotation reduces the risk of compromised keys being used for extended periods.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key#rotation_policy", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-320", + "descriptionID": "ca1ffce5", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego new file mode 100644 index 00000000000..13ca1cc6da7 --- /dev/null +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego @@ -0,0 +1,17 @@ +package Cx + +# REGLA 1: La clave del Key Vault no tiene política de rotación configurada. +CxPolicy[result] { + doc := input.document[i] + key := doc.resource.azurerm_key_vault_key[name] + + not key.rotation_policy + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_key_vault_key.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_key_vault_key.%s' should have a 'rotation_policy' block defined", [name]), + "keyActualValue": sprintf("'azurerm_key_vault_key.%s' does not have a 'rotation_policy' block defined", [name]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/negative1.tf new file mode 100644 index 00000000000..af70d50c07c --- /dev/null +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/negative1.tf @@ -0,0 +1,16 @@ +resource "azurerm_key_vault_key" "pass" { + name = "pass-key" + key_vault_id = "vault-id" + key_type = "RSA" + key_size = 2048 + key_opts = ["decrypt", "encrypt"] + + rotation_policy { + expire_after = "P90D" + notify_before_expiry = "P29D" + + automatic { + time_before_expiry = "P30D" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/positive1.tf new file mode 100644 index 00000000000..4944d9b302e --- /dev/null +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/positive1.tf @@ -0,0 +1,7 @@ +resource "azurerm_key_vault_key" "fail" { + name = "fail-key" + key_vault_id = "vault-id" + key_type = "RSA" + key_size = 2048 + key_opts = ["decrypt", "encrypt"] +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..e3ffd2c068e --- /dev/null +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "Key Vault Key Rotation Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/README.md new file mode 100644 index 00000000000..8cb4d412bcc --- /dev/null +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/README.md @@ -0,0 +1,60 @@ +# Regla KICS: Azure Managed Lustre Not Encrypted with CMK + +## Descripción General + +Esta regla de KICS verifica que los sistemas de archivos **Azure Managed Lustre** (`azurerm_managed_lustre_file_system`) estén configurados para utilizar claves gestionadas por el cliente (**Customer-Managed Keys - CMK**) para el cifrado de datos en reposo. + +Por defecto, Azure cifra los datos en Lustre utilizando claves gestionadas por la plataforma. Para cumplir con requisitos de soberanía de datos y gobernanza, se recomienda el uso de CMK mediante el bloque `encryption_key`. Esto otorga a las organizaciones control total sobre el ciclo de vida de la clave, permitiendo la rotación y revocación selectiva del acceso a los datos de alto rendimiento almacenados en el sistema de archivos. + +## Lógica de la Regla + +La política analiza el recurso `azurerm_managed_lustre_file_system` validando la siguiente condición: +1. **Presencia del Bloque de Cifrado:** Se verifica la existencia del bloque `encryption_key`. Si este bloque no está definido, el sistema de archivos utiliza por defecto el cifrado gestionado por Azure. + +## Caso de Fallo Detectado + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso Único: Uso de Claves Gestionadas por la Plataforma (Bloque Ausente) + +* **Descripción:** El sistema de archivos Lustre se define sin el bloque de configuración de cifrado por cliente, lo que delega la protección de los datos a las claves por defecto de la plataforma. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_managed_lustre_file_system" "example_insecure" { + name = "insecure-lustre" + resource_group_name = "rg-example" + location = "West Europe" + sku_name = "AMLFS-Durable-Premium-250" + subnet_id = azurerm_subnet.example.id + storage_capacity_in_tb = 48 + + # El recurso carece del bloque encryption_key + } + ``` +* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_managed_lustre_file_system`. + +## Recurso Involucrado + +* `azurerm_managed_lustre_file_system` + +## Solución + +Para solucionar este riesgo, defina el bloque `encryption_key` proporcionando la URL de la clave y el ID del Key Vault de origen. + +```terraform +resource "azurerm_managed_lustre_file_system" "secure_lustre" { + name = "secure-lustre" + resource_group_name = "rg-example" + location = "West Europe" + sku_name = "AMLFS-Durable-Premium-250" + subnet_id = azurerm_subnet.example.id + storage_capacity_in_tb = 48 + + # SOLUCIÓN: Configurar cifrado con CMK + encryption_key { + key_url = azurerm_key_vault_key.example.id + source_vault_id = azurerm_key_vault.example.id + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json new file mode 100644 index 00000000000..752e13181c2 --- /dev/null +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "7fc653e2-af91-4379-9219-5095caba0ff6", + "queryName": "Azure Managed Lustre Not Encrypted with CMK", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that Azure Managed Lustre file systems are encrypted using a Customer-Managed Key (CMK). By default, data is encrypted with platform-managed keys, but CMK provides full control over key rotation and access policies.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/managed_lustre_file_system#key_encryption_key", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-326", + "descriptionID": "7fc653e2", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego new file mode 100644 index 00000000000..d0b0f475678 --- /dev/null +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego @@ -0,0 +1,17 @@ +package Cx + +# REGLA 1: El bloque 'encryption_key' no está definido. +CxPolicy[result] { + doc := input.document[i] + lustre := doc.resource.azurerm_managed_lustre_file_system[name] + + not lustre.encryption_key + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_managed_lustre_file_system.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_managed_lustre_file_system.%s' should have an 'encryption_key' block defined", [name]), + "keyActualValue": sprintf("'azurerm_managed_lustre_file_system.%s' is missing the 'encryption_key' block", [name]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/negative1.tf new file mode 100644 index 00000000000..e259cb89f05 --- /dev/null +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/negative1.tf @@ -0,0 +1,13 @@ +resource "azurerm_managed_lustre_file_system" "pass" { + name = "pass-lustre" + resource_group_name = "rg" + location = "West Europe" + sku_name = "AMLFS-Durable-Premium-250" + subnet_id = "subnet-id" + storage_capacity_in_tb = 48 + + encryption_key { + key_url = "https://kv.vault.azure.net/keys/key/v1" + source_vault_id = "/subscriptions/000/resourceGroups/rg/providers/Microsoft.KeyVault/vaults/kv" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/positive1.tf new file mode 100644 index 00000000000..33d647029e0 --- /dev/null +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/positive1.tf @@ -0,0 +1,8 @@ +resource "azurerm_managed_lustre_file_system" "fail" { + name = "fail-lustre" + resource_group_name = "rg" + location = "West Europe" + sku_name = "AMLFS-Durable-Premium-250" + subnet_id = "subnet-id" + storage_capacity_in_tb = 48 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..256fed25d3e --- /dev/null +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "Azure Managed Lustre Not Encrypted with CMK", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/README.md b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/README.md new file mode 100644 index 00000000000..2999db498d9 --- /dev/null +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/README.md @@ -0,0 +1,59 @@ +# Regla KICS: MySQL Audit Log Enabled (Manual) + +## Descripción General + +Esta regla de KICS actúa como un control manual para asegurar que el parámetro de servidor `audit_log_enabled` esté configurado en `ON` en las instancias de **Azure Database for MySQL**. + +Los registros de auditoría son fundamentales para la observabilidad y la seguridad de la base de datos. Permiten rastrear eventos específicos, como intentos de conexión, ejecución de consultas DDL y cambios en privilegios de usuario. Debido a que en Azure MySQL estos parámetros pueden gestionarse de forma externa al recurso del servidor (ya sea por el portal o mediante recursos de configuración independientes), se requiere una validación manual para confirmar el cumplimiento. + +## Lógica de la Regla + +Dado que la configuración de auditoría no reside obligatoriamente dentro del bloque principal del servidor MySQL en Terraform, el análisis estático se centra en: +1. **Identificación de Recursos:** La regla localiza todos los recursos de tipo `azurerm_mssql_server` y `azurerm_mysql_flexible_server`. +2. **Recordatorio de Auditoría:** Genera un hallazgo de severidad informativa para alertar al administrador de la necesidad de verificar el estado del parámetro `audit_log_enabled`. + +## Caso de Fallo Detectado + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso Único: Verificación Manual Requerida + +* **Descripción:** Se detecta la presencia de un servidor MySQL. Dado que el estado de la auditoría no siempre es verificable estáticamente desde el recurso del servidor, se solicita revisión manual. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_mssql_server" "example_insecure" { + name = "mysql-server-audit-check" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + # El estado de audit_log_enabled no es visible aquí. + } + ``` +* **Ubicación de la Alerta:** Sobre el recurso del servidor MySQL detectado. + +## Recurso Involucrado + +* `azurerm_mssql_server` +* `azurerm_mysql_flexible_server` + +## Solución + +Existen dos métodos para asegurar que la auditoría esté habilitada: + +### Opción A: Verificación Manual (Portal de Azure) +1. Navegue a su servidor MySQL en el Portal de Azure. +2. Acceda a la sección **Parámetros del servidor**. +3. Busque el parámetro `audit_log_enabled` y confirme que su valor sea `ON`. + +### Opción B: Configuración como Código (Recomendado) +Utilice el recurso `azurerm_mysql_configuration` (para servidores Single Server) o `azurerm_mysql_flexible_server_configuration` (para Flexible Server) para forzar el parámetro: + +```terraform +# Ejemplo para MySQL Single Server +resource "azurerm_mysql_configuration" "audit_log" { + name = "audit_log_enabled" + resource_group_name = azurerm_resource_group.example.name + server_name = azurerm_mssql_server.example.name + value = "ON" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json new file mode 100644 index 00000000000..11e04045ca4 --- /dev/null +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "8d8ac482-16c2-4eb7-bfab-e2d94d035498", + "queryName": "MySQL Audit Log Enabled (Manual)", + "severity": "INFO", + "category": "Observability", + "descriptionText": "Ensures that the 'audit_log_enabled' server parameter is set to 'ON' for Azure MySQL Database Servers. Since this parameter is often managed via runtime configurations or separate resources, manual verification is required.", + "descriptionUrl": "https://learn.microsoft.com/en-us/azure/mysql/single-server/concepts-audit-logs", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-778", + "descriptionID": "8d8ac482", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego new file mode 100644 index 00000000000..5c28617c5cf --- /dev/null +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego @@ -0,0 +1,19 @@ +package Cx + +targets := {"azurerm_mssql_server", "azurerm_mysql_flexible_server"} + +# REGLA MANUAL: Detecta servidores MySQL para solicitar verificación de logs de auditoría. +CxPolicy[result] { + doc := input.document[i] + + resource_type := targets[t] + server := doc.resource[resource_type][name] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.%s.%s", [resource_type, name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'audit_log_enabled' should be set to 'ON' for '%s.%s' (Manual Verification)", [resource_type, name]), + "keyActualValue": "Logging configuration requires manual verification or check of 'azurerm_mysql_configuration' resources", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive1.tf b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive1.tf new file mode 100644 index 00000000000..98f95c296a0 --- /dev/null +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive1.tf @@ -0,0 +1,8 @@ +resource "azurerm_mssql_server" "fail_single" { + name = "mysql-server-1" + resource_group_name = "rg-test" + location = "West Europe" + administrator_login = "mysqladmin" + administrator_login_password = "Password1234!" + version = "5.7" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive2.tf b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive2.tf new file mode 100644 index 00000000000..9cdb9785156 --- /dev/null +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive2.tf @@ -0,0 +1,7 @@ +resource "azurerm_mysql_flexible_server" "fail_flexible" { + name = "mysql-flex-server-1" + resource_group_name = "rg-test" + location = "West Europe" + administrator_login = "mysqladmin" + administrator_password = "Password1234!" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..17539402a93 --- /dev/null +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "MySQL Audit Log Enabled (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "MySQL Audit Log Enabled (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/README.md b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/README.md new file mode 100644 index 00000000000..ade2b20eddb --- /dev/null +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/README.md @@ -0,0 +1,59 @@ +# Regla KICS: MySQL Audit Log Events Connection (Manual) + +## Descripción General + +Esta regla de KICS actúa como un control manual para verificar que el parámetro de servidor `audit_log_events` incluya el valor `CONNECTION` en los servidores de **Azure Database for MySQL**. + +El registro de los eventos de tipo `CONNECTION` es una pieza fundamental de la estrategia de seguridad y cumplimiento. Permite a los administradores y auditores rastrear quién accede a la base de datos, detectar ataques de fuerza bruta (intentos fallidos) y auditar sesiones sospechosas. Sin esta configuración, se pierde visibilidad sobre el acceso inicial a los recursos de datos, dificultando la respuesta ante incidentes. + +## Lógica de la Regla + +Debido a que el análisis estático no siempre puede garantizar la verificación de una cadena de texto dentro de un recurso de configuración independiente (`azurerm_mysql_configuration`), esta regla aplica un enfoque preventivo: +1. **Identificación de Recursos:** Detecta todas las instancias de `azurerm_mssql_server` y `azurerm_mysql_flexible_server`. +2. **Recordatorio de Seguridad:** Genera una alerta informativa para que el auditor verifique específicamente que el evento de conexión esté siendo capturado. + +## Caso de Fallo Detectado + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso Único: Verificación Manual Requerida + +* **Descripción:** Se detecta un servidor MySQL aprovisionado. KICS emite una alerta para asegurar que los tipos de eventos auditados incluyan las conexiones, ya que esta configuración puede estar delegada a otros recursos o al portal. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_mssql_server" "example_audit_check" { + name = "mysql-server-connection-check" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + # El contenido de audit_log_events no es verificable aquí. + } + ``` +* **Ubicación de la Alerta:** Sobre el recurso del servidor MySQL detectado. + +## Recurso Involucrado + +* `azurerm_mssql_server` +* `azurerm_mysql_flexible_server` + +## Solución + +### Opción A: Verificación Manual (Portal de Azure) +1. Navegue al servidor MySQL en el Portal de Azure. +2. Vaya a la sección **Parámetros del servidor**. +3. Localice el parámetro `audit_log_events`. +4. Asegúrese de que entre los valores seleccionados se incluya `CONNECTION`. + +### Opción B: Configuración mediante Terraform +Asegúrese de incluir explícitamente el valor en el recurso de configuración: + +```terraform +resource "azurerm_mysql_configuration" "audit_events" { + name = "audit_log_events" + resource_group_name = azurerm_resource_group.example.name + server_name = azurerm_mssql_server.example.name + + # SOLUCIÓN: Incluir CONNECTION en la lista de eventos + value = "CONNECTION,QUERY,DDL" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json new file mode 100644 index 00000000000..d5160af4619 --- /dev/null +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "fe65cd89-28ea-4301-9c50-6dee30553557", + "queryName": "MySQL Audit Log Events Connection (Manual)", + "severity": "INFO", + "category": "Observability", + "descriptionText": "Ensures that the 'audit_log_events' server parameter includes 'CONNECTION' for Azure MySQL Database Servers. This ensures that successful and failed connection attempts are logged.", + "descriptionUrl": "https://learn.microsoft.com/en-us/azure/mysql/single-server/concepts-audit-logs", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-778", + "descriptionID": "fe65cd89", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego new file mode 100644 index 00000000000..91355c01e0e --- /dev/null +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego @@ -0,0 +1,19 @@ +package Cx + +targets := {"azurerm_mssql_server", "azurerm_mysql_flexible_server"} + +# REGLA MANUAL: Detecta servidores MySQL para solicitar verificación del evento CONNECTION. +CxPolicy[result] { + doc := input.document[i] + + resource_type := targets[t] + server := doc.resource[resource_type][name] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.%s.%s", [resource_type, name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'audit_log_events' should include 'CONNECTION' for '%s.%s' (Manual Verification)", [resource_type, name]), + "keyActualValue": "Audit log event configuration requires manual verification or check of 'azurerm_mysql_configuration'", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive1.tf b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive1.tf new file mode 100644 index 00000000000..d406e50d290 --- /dev/null +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive1.tf @@ -0,0 +1,8 @@ +resource "azurerm_mssql_server" "fail_single" { + name = "mysql-server-connection-fail" + resource_group_name = "rg-test" + location = "West Europe" + administrator_login = "mysqladmin" + administrator_login_password = "Password1234!" + version = "5.7" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive2.tf b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive2.tf new file mode 100644 index 00000000000..f9529c2d915 --- /dev/null +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive2.tf @@ -0,0 +1,7 @@ +resource "azurerm_mysql_flexible_server" "fail_flexible" { + name = "mysql-flex-server-connection-fail" + resource_group_name = "rg-test" + location = "West Europe" + administrator_login = "mysqladmin" + administrator_password = "Password1234!" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..2b4dd87ee4a --- /dev/null +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "MySQL Audit Log Events Connection (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "MySQL Audit Log Events Connection (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/README.md new file mode 100644 index 00000000000..fbdc28464c5 --- /dev/null +++ b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/README.md @@ -0,0 +1,65 @@ +# Regla KICS: NetApp Account CMK Encryption Disabled + +## Descripción General + +Esta regla de KICS verifica que las cuentas de **Azure NetApp Files** estén configuradas para utilizar claves gestionadas por el cliente (**Customer-Managed Keys - CMK**) para el cifrado de datos en reposo. + +Por defecto, Azure NetApp Files cifra los datos utilizando claves gestionadas por la plataforma Microsoft. Sin embargo, para cumplir con requisitos de cumplimiento normativo y soberanía de datos, se recomienda el uso de CMK. Esto permite a las organizaciones tener el control total sobre el ciclo de vida de las claves, incluyendo la rotación y la revocación de acceso, asegurando que los volúmenes de almacenamiento de alto rendimiento estén protegidos por claves bajo el control directo del cliente en Azure Key Vault. + +## Lógica de la Regla + +La política analiza la configuración de Terraform buscando dos métodos válidos de implementación de CMK: +1. **Configuración Inline:** Verifica si el recurso `azurerm_netapp_account` tiene un bloque `encryption` donde el atributo `key_source` sea explícitamente `Microsoft.KeyVault`. +2. **Recurso Independiente:** Verifica si existe un recurso `azurerm_netapp_account_encryption` vinculado al ID de la cuenta NetApp analizada. + +Si no se detecta ninguno de estos dos métodos, se genera una alerta indicando que la cuenta está operando con el cifrado predeterminado de la plataforma. + +## Caso de Fallo Detectado + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso Único: Configuración de Cifrado por Defecto (Platform Keys) + +* **Descripción:** Se define la cuenta de NetApp sin habilitar el uso de Key Vault para el cifrado, dejando los datos protegidos únicamente por las claves de Microsoft. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_netapp_account" "fail" { + name = "insecure-netapp-account" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + + # Falta la configuración de CMK (inline o recurso separado) + } + ``` +* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_netapp_account`. + +## Recursos Involucrados + +* `azurerm_netapp_account` +* `azurerm_netapp_account_encryption` + +## Solución + +Para solucionar este riesgo, asigne una identidad gestionada a la cuenta y utilice el recurso `azurerm_netapp_account_encryption` para vincular la clave del Key Vault. + +```terraform +resource "azurerm_netapp_account" "secure" { + name = "secure-netapp-account" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + + # 1. Asignar identidad + identity { + type = "UserAssigned" + identity_ids = [azurerm_user_assigned_identity.example.id] + } +} + +# 2. Configurar el cifrado CMK mediante el recurso dedicado +resource "azurerm_netapp_account_encryption" "secure_encryption" { + netapp_account_id = azurerm_netapp_account.secure.id + user_assigned_identity_id = azurerm_user_assigned_identity.example.id + encryption_key = azurerm_key_vault_key.example.versionless_id +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json new file mode 100644 index 00000000000..e98c7036089 --- /dev/null +++ b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "8bed44b5-bcd6-42f4-b7b6-f59fd4edc94a", + "queryName": "NetApp Account CMK Encryption Disabled", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that Azure NetApp Files accounts are configured to use Customer-Managed Keys (CMK) for encryption, instead of the default platform-managed keys.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/netapp_account_encryption", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-326", + "descriptionID": "8bed44b5", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego new file mode 100644 index 00000000000..aaef399b3a3 --- /dev/null +++ b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego @@ -0,0 +1,36 @@ +package Cx + +has_encryption_resource(doc, account_id) { + enc := doc.resource.azurerm_netapp_account_encryption[_] + check_id(enc.netapp_account_id, account_id) +} + +check_id(current, target) { + current == target +} + +check_id(current, target) { + current == sprintf("${%s}", [target]) +} + +has_inline_encryption(account) { + account.encryption.key_source == "Microsoft.KeyVault" +} + +# REGLA 1: La cuenta NetApp utiliza Platform-Managed Keys (falta configuración CMK). +CxPolicy[result] { + doc := input.document[i] + account := doc.resource.azurerm_netapp_account[name] + account_id := sprintf("azurerm_netapp_account.%s.id", [name]) + + not has_inline_encryption(account) + not has_encryption_resource(doc, account_id) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_netapp_account.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_netapp_account.%s' should have 'encryption.key_source' set to 'Microsoft.KeyVault' or have an 'azurerm_netapp_account_encryption' resource associated", [name]), + "keyActualValue": sprintf("'azurerm_netapp_account.%s' is using Platform-Managed Keys (default)", [name]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/negative1.tf new file mode 100644 index 00000000000..610c7e965bf --- /dev/null +++ b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/negative1.tf @@ -0,0 +1,16 @@ +resource "azurerm_netapp_account" "pass" { + name = "pass-netapp" + resource_group_name = "rg-example" + location = "West Europe" + + identity { + type = "UserAssigned" + identity_ids = ["/subscriptions/000/resourceGroups/rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id"] + } +} + +resource "azurerm_netapp_account_encryption" "pass_encryption" { + netapp_account_id = azurerm_netapp_account.pass.id + user_assigned_identity_id = "/subscriptions/000/resourceGroups/rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id" + encryption_key = "https://kv.vault.azure.net/keys/key/v1" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive1.tf new file mode 100644 index 00000000000..76a7edb055f --- /dev/null +++ b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive1.tf @@ -0,0 +1,5 @@ +resource "azurerm_netapp_account" "fail" { + name = "fail-netapp" + resource_group_name = "rg-example" + location = "West Europe" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..40945f981f6 --- /dev/null +++ b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "NetApp Account CMK Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/README.md b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/README.md new file mode 100644 index 00000000000..4c089125f9b --- /dev/null +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/README.md @@ -0,0 +1,67 @@ +# Regla KICS: Azure PaaS Services Private Endpoint Disabled (Master) + +## Descripción General + +Esta es una regla consolidada (**Regla Maestra**) diseñada para asegurar que los servicios PaaS críticos de Azure estén protegidos mediante el uso de **Private Endpoints**. + +Los Private Endpoints (Puntos de Conexión Privados) son un componente esencial de la seguridad perimetral en Azure. Permiten que los servicios (como bases de datos, almacenamiento o bóvedas de claves) se integren directamente en una Red Virtual (VNet). Al asignar una dirección IP privada del espacio de la VNet al servicio, se elimina la necesidad de exponer dichos recursos a la internet pública, reduciendo drásticamente la superficie de ataque y previniendo la exfiltración de datos. + +## Lógica de la Regla + +La política analiza de forma exhaustiva los recursos definidos en Terraform buscando una vinculación válida: +1. **Recursos Objetivo:** La regla monitorea una lista extensa de servicios, incluyendo `azurerm_storage_account`, `azurerm_mssql_server`, `azurerm_cosmosdb_account`, `azurerm_key_vault` y otros servicios de datos y mensajería. +2. **Validación de Vínculo:** Para cada recurso detectado, busca la existencia de un recurso `azurerm_private_endpoint` que lo referencia a través del atributo `private_connection_resource_id`. +3. **Resultado:** Si el recurso PaaS existe pero no hay un endpoint privado asociado en el mismo contexto de código, se genera una alerta. + +## Limitaciones del Análisis Estático + +Es importante notar que esta regla valida la configuración **dentro del mismo archivo o estado de Terraform**. Debido a la naturaleza del análisis estático: +* No puede validar conexiones si el recurso se crea en una suscripción distinta o se gestiona en un estado de Terraform separado. +* Podría generar falsos positivos si el endpoint se define mediante módulos externos cuyas variables no son resueltas por el motor de escaneo. + +## Caso de Fallo Detectado + +A continuación se describe el escenario principal que esta política detectará. + +--- + +### Caso Único: Recurso PaaS Aislado (Sin Endpoint Privado) + +* **Descripción:** Se ha definido un servicio crítico (ej. Azure SQL o Storage Account) pero no se ha aprovisionado el endpoint privado que garantice que el tráfico sea interno a la VNet. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_storage_account" "example_insecure" { + name = "stinsecuredata" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "LRS" + + # El recurso existe pero carece de un azurerm_private_endpoint vinculado + } + ``` +* **Ubicación de la Alerta:** Sobre el recurso PaaS identificado (Storage, SQL, Key Vault, etc.). + +## Recursos Involucrados + +* `azurerm_private_endpoint` +* Servicios PaaS (Storage, SQL, Cosmos, KeyVault, ACR, ServiceBus, etc.) + +## Solución + +Para solucionar este hallazgo, debe crear un recurso `azurerm_private_endpoint` y vincularlo al ID del recurso PaaS mediante el bloque `private_service_connection`. + +```terraform +resource "azurerm_private_endpoint" "example_secure" { + name = "pe-storage" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + subnet_id = azurerm_subnet.example.id + + private_service_connection { + name = "psc-storage" + private_connection_resource_id = azurerm_storage_account.example_insecure.id + is_manual_connection = false + subresource_names = ["blob"] + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json new file mode 100644 index 00000000000..a17522eb843 --- /dev/null +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "dda11a20-c7c2-43f8-bd52-a4c029ad15e4", + "queryName": "Ensure Private Endpoints Are Used Where Possible", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that key Azure PaaS services (Cosmos DB, Storage, SQL, KeyVault, ACR, etc.) are accessed via Private Endpoints. While static analysis cannot resolve IDs across different state files, this rule validates local resource linkages.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-200", + "descriptionID": "dda11a20", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego new file mode 100644 index 00000000000..fc1b7a752a0 --- /dev/null +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego @@ -0,0 +1,54 @@ +package Cx + +targets := { + "azurerm_cosmosdb_account", + "azurerm_storage_account", + "azurerm_mssql_server", + "azurerm_key_vault", + "azurerm_container_registry", + "azurerm_servicebus_namespace", + "azurerm_mariadb_server", + "azurerm_postgresql_server", + "azurerm_mysql_server", + "azurerm_redis_cache", + "azurerm_eventhub_namespace", + "azurerm_automation_account", + "azurerm_data_factory", + "azurerm_synapse_workspace", + "azurerm_search_service" +} + +# REGLA MAESTRA: Verifica si los recursos de la lista targets tienen un Private Endpoint vinculado. +CxPolicy[result] { + doc := input.document[i] + + resource_type := targets[t] + resource_instances := doc.resource[resource_type] + resource_instance := resource_instances[name] + + target_id := sprintf("%s.%s.id", [resource_type, name]) + + private_endpoints := [pe | + pe := doc.resource.azurerm_private_endpoint[_] + conn := pe.private_service_connection + check_resource_id(conn.private_connection_resource_id, target_id) + ] + + count(private_endpoints) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.%s.%s", [resource_type, name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'%s.%s' should be linked to an 'azurerm_private_endpoint'", [resource_type, name]), + "keyActualValue": sprintf("'%s.%s' is not linked to any 'azurerm_private_endpoint' in this file", [resource_type, name]), + } +} + +check_resource_id(current, target) { + current == target +} + +check_resource_id(current, target) { + current == sprintf("${%s}", [target]) +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/negative1.tf b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/negative1.tf new file mode 100644 index 00000000000..cfd1a9fb026 --- /dev/null +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/negative1.tf @@ -0,0 +1,22 @@ +resource "azurerm_mssql_server" "pass_sql" { + name = "sqlpassserver" + resource_group_name = "rg" + location = "West Europe" + version = "12.0" + administrator_login = "admin" + administrator_login_password = "Password123!" +} + +resource "azurerm_private_endpoint" "pass_pe" { + name = "pe-sql" + location = "West Europe" + resource_group_name = "rg" + subnet_id = "subnet-id" + + private_service_connection { + name = "psc-sql" + private_connection_resource_id = azurerm_mssql_server.pass_sql.id + is_manual_connection = false + subresource_names = ["sqlServer"] + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive1.tf b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive1.tf new file mode 100644 index 00000000000..0d675c14d24 --- /dev/null +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive1.tf @@ -0,0 +1,7 @@ +resource "azurerm_storage_account" "fail_storage" { + name = "storagefail" + resource_group_name = "rg" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive2.tf b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive2.tf new file mode 100644 index 00000000000..f65468b751e --- /dev/null +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive2.tf @@ -0,0 +1,7 @@ +resource "azurerm_key_vault" "fail_kv" { + name = "kvfail" + location = "West Europe" + resource_group_name = "rg" + tenant_id = "00000000-0000-0000-0000-000000000000" + sku_name = "standard" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..e92aa602481 --- /dev/null +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Ensure Private Endpoints Are Used Where Possible", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Ensure Private Endpoints Are Used Where Possible", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/README.md b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/README.md new file mode 100644 index 00000000000..f5ae5d05d63 --- /dev/null +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/README.md @@ -0,0 +1,69 @@ +# Regla KICS: Production Workload using Basic or Consumption SKU + +## Descripción General + +Esta regla identifica recursos de Azure configurados con niveles de precios (SKUs) de tipo **Basic**, **Free** o **Consumption**. + +Aunque estos niveles son ideales para entornos de desarrollo, aprendizaje o pruebas de concepto (PoC), carecen de características fundamentales necesarias para entornos de producción. El uso de estos SKUs en producción compromete la fiabilidad del servicio debido a la ausencia de Acuerdos de Nivel de Servicio (SLA) garantizados, falta de soporte para integración con redes virtuales (VNet), ausencia de slots de implementación y latencias imprevistas ("cold starts") en modelos de consumo serverless. + +## Lógica de la Regla + +La política audita los siguientes recursos en la configuración de Terraform: +1. **Service Plans (`azurerm_service_plan`):** Alerta si el atributo `sku_name` se establece en niveles no productivos como B1-B3, F1, FREE o Y1. +2. **API Management (`azurerm_api_management`):** Alerta si el atributo `sku_name` coincide con patrones de tipo "Basic" o "Consumption". + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Service Plan en Nivel No-Productivo + +* **Descripción:** Se detecta un plan de App Service configurado en nivel Basic o Free, lo cual limita la disponibilidad y las capacidades de red del servicio. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_service_plan" "fail_plan" { + name = "example-basic-plan" + resource_group_name = "rg-production" + location = "West Europe" + os_type = "Linux" + sku_name = "B1" # <-- FALLO: Nivel Basic + } + ``` +* **Ubicación de la Alerta:** Atributo `sku_name`. + +--- + +### Caso 2: API Management en Modo Consumo + +* **Descripción:** Se detecta una instancia de APIM en nivel Consumption (Serverless), lo que puede afectar al rendimiento y carece de aislamiento de red. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_api_management" "fail_apim" { + name = "example-apim" + sku_name = "Consumption_0" # <-- FALLO: Nivel Consumption + # ... resto de la configuración ... + } + ``` +* **Ubicación de la Alerta:** Atributo `sku_name`. + +## Recurso Involucrado + +* `azurerm_service_plan` +* `azurerm_api_management` + +## Solución + +Actualice el SKU del recurso a un nivel orientado a producción, como **Standard (S)** o **Premium (P)**, para garantizar el SLA y las funciones de red necesarias. + +```terraform +resource "azurerm_service_plan" "secure_production" { + name = "prod-service-plan" + resource_group_name = "rg-production" + location = "West Europe" + os_type = "Linux" + + # SOLUCIÓN: Usar un nivel Standard o superior + sku_name = "S1" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json new file mode 100644 index 00000000000..4ff2bbda593 --- /dev/null +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "bd3a6fc3-fadb-472b-b06c-54c7d7645f15", + "queryName": "Production Workload using Basic or Consumption SKU", + "severity": "LOW", + "category": "Resource Management", + "descriptionText": "Detects the use of Basic, Free, or Consumption SKUs in Azure resources. These SKUs are often unsuitable for production workloads due to lack of SLAs, VNet integration support, or 'cold start' issues.", + "descriptionUrl": "https://azure.microsoft.com/en-us/pricing/details/app-service/linux/", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-1038", + "descriptionID": "bd3a6fc3", + "riskScore": 2.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego new file mode 100644 index 00000000000..4433742de6c --- /dev/null +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego @@ -0,0 +1,34 @@ +package Cx + +# REGLA 1: Azure Service Plan usando SKU Basic (B), Free (F) o Consumption (Y1). +CxPolicy[result] { + doc := input.document[i] + plan := doc.resource.azurerm_service_plan[name] + + invalid_skus := ["B1", "B2", "B3", "F1", "FREE", "Y1"] + plan.sku_name == invalid_skus[_] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_service_plan.%s.sku_name", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": sprintf("'%s.sku_name' should be Standard (S), Premium (P) or Isolated (I) for production", [name]), + "keyActualValue": sprintf("'%s.sku_name' is set to '%s' (Basic/Free/Consumption)", [name, plan.sku_name]), + } +} + +# REGLA 2: Azure API Management usando SKU Basic o Consumption. +CxPolicy[result] { + doc := input.document[i] + apim := doc.resource.azurerm_api_management[name] + + regex.match("(Basic|Consumption).*", apim.sku_name) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_api_management.%s.sku_name", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": sprintf("'%s.sku_name' should be Standard or Premium for production features", [name]), + "keyActualValue": sprintf("'%s.sku_name' is set to '%s'", [name, apim.sku_name]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/negative1.tf b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/negative1.tf new file mode 100644 index 00000000000..78a4362db6a --- /dev/null +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/negative1.tf @@ -0,0 +1,7 @@ +resource "azurerm_service_plan" "pass_sp" { + name = "pass-sp" + resource_group_name = "rg" + location = "West Europe" + os_type = "Linux" + sku_name = "S1" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/negative2.tf b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/negative2.tf new file mode 100644 index 00000000000..af8313b8440 --- /dev/null +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/negative2.tf @@ -0,0 +1,8 @@ +resource "azurerm_api_management" "pass_apim" { + name = "pass-apim" + location = "West Europe" + resource_group_name = "rg" + publisher_name = "Company" + publisher_email = "email@test.com" + sku_name = "Standard_1" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive1.tf b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive1.tf new file mode 100644 index 00000000000..97884022dc3 --- /dev/null +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive1.tf @@ -0,0 +1,7 @@ +resource "azurerm_service_plan" "fail_sp" { + name = "fail-sp" + resource_group_name = "rg" + location = "West Europe" + os_type = "Linux" + sku_name = "B1" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive2.tf b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive2.tf new file mode 100644 index 00000000000..fe09c001e18 --- /dev/null +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive2.tf @@ -0,0 +1,8 @@ +resource "azurerm_api_management" "fail_apim" { + name = "fail-apim" + location = "West Europe" + resource_group_name = "rg" + publisher_name = "Company" + publisher_email = "email@test.com" + sku_name = "Consumption_0" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive_expected_result.json new file mode 100644 index 00000000000..0e52a4b0071 --- /dev/null +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Production Workload using Basic or Consumption SKU", + "severity": "LOW", + "line": 6, + "fileName": "positive1.tf" + }, + { + "queryName": "Production Workload using Basic or Consumption SKU", + "severity": "LOW", + "line": 7, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/README.md new file mode 100644 index 00000000000..e4cf7cd3af5 --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/README.md @@ -0,0 +1,61 @@ +# Regla KICS: Recovery Services Vault CMK Encryption Disabled + +## Descripción General + +Esta regla de KICS verifica que los almacenes de **Recovery Services Vault** (utilizados para Azure Backup y Azure Site Recovery) estén configurados para utilizar claves gestionadas por el cliente (**Customer-Managed Keys - CMK**) para el cifrado de datos en reposo. + +Por defecto, los datos respaldados se cifran mediante claves gestionadas por la plataforma de Microsoft. Sin embargo, para cumplir con requisitos de cumplimiento normativo y garantizar la soberanía de los datos, las organizaciones deben utilizar sus propias claves almacenadas en Azure Key Vault. Esto permite un control total sobre la rotación de claves, las políticas de acceso y la capacidad de revocar el acceso a los datos de respaldo en caso de necesidad. + +## Lógica de la Regla + +La política analiza el recurso `azurerm_recovery_services_vault` validando la siguiente condición técnica: +1. **Presencia del Bloque de Cifrado:** Se comprueba la existencia del bloque `encryption`. La ausencia de este bloque implica que el almacén utiliza el cifrado predeterminado gestionado por la plataforma, lo cual no cumple con los requisitos de CMK. + +## Caso de Fallo Detectado + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso Único: Uso de Claves de la Plataforma (Cifrado por Defecto) + +* **Descripción:** Se define el Recovery Services Vault sin el bloque de configuración de cifrado por cliente, delegando la protección de los datos a las claves automáticas de Azure. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_recovery_services_vault" "fail_vault" { + name = "insecure-vault" + location = "West Europe" + resource_group_name = "rg-production" + sku = "Standard" + + # El recurso carece del bloque encryption {} + } + ``` +* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_recovery_services_vault`. + +## Recurso Involucrado + +* `azurerm_recovery_services_vault` + +## Solución + +Para solucionar este hallazgo, debe habilitar una identidad gestionada en el Vault y configurar el bloque `encryption` proporcionando obligatoriamente el `key_id` de Azure Key Vault. + +```terraform +resource "azurerm_recovery_services_vault" "secure_vault" { + name = "secure-recovery-vault" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + sku = "Standard" + + # 1. Habilitar identidad para acceso al Key Vault + identity { + type = "SystemAssigned" + } + + # 2. Configurar el cifrado CMK (key_id es obligatorio en este bloque) + encryption { + key_id = azurerm_key_vault_key.example.id + use_system_assigned_identity = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json new file mode 100644 index 00000000000..588fbca70b7 --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "9436d439-99f6-4f81-bef2-e7f50d24d453", + "queryName": "Recovery Services Vault CMK Encryption Disabled", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that Azure Recovery Services Vaults are encrypted using Customer-Managed Keys (CMK) stored in Azure Key Vault. Using CMK provides control over key lifecycle and access policies, unlike the default platform-managed keys.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/recovery_services_vault#encryption", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-326", + "descriptionID": "9436d439", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego new file mode 100644 index 00000000000..3926d795315 --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego @@ -0,0 +1,17 @@ +package Cx + +# REGLA 1: El bloque de encriptación no está definido. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_recovery_services_vault[name] + + not vault.encryption + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_recovery_services_vault.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_recovery_services_vault.%s' should have an 'encryption' block defined with a valid 'key_id'", [name]), + "keyActualValue": sprintf("'azurerm_recovery_services_vault.%s' is missing the 'encryption' block (Platform-Managed Keys by default)", [name]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/negative1.tf new file mode 100644 index 00000000000..3469d90f314 --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/negative1.tf @@ -0,0 +1,16 @@ +resource "azurerm_recovery_services_vault" "pass" { + name = "vault-pass" + location = "West Europe" + resource_group_name = "rg-test" + sku = "Standard" + + identity { + type = "SystemAssigned" + } + + encryption { + key_id = "https://kv.vault.azure.net/keys/key/v1" + infrastructure_encryption_enabled = true + use_system_assigned_identity = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive1.tf new file mode 100644 index 00000000000..8f2bb000720 --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive1.tf @@ -0,0 +1,7 @@ +resource "azurerm_recovery_services_vault" "fail" { + name = "vault-fail" + location = "West Europe" + resource_group_name = "rg-test" + sku = "Standard" + # Falla por ausencia de bloque encryption +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..ff3d72812a2 --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "Recovery Services Vault CMK Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/README.md b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/README.md new file mode 100644 index 00000000000..59e612fbeec --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/README.md @@ -0,0 +1,72 @@ +# Regla KICS: Recovery Services Vault Cross Region Restore Disabled + +## Descripción General + +Esta regla de KICS verifica que la funcionalidad de **Restauración entre Regiones** (`cross_region_restore_enabled`) esté habilitada en los almacenes de **Recovery Services Vault**. + +Habilitar la Restauración entre Regiones (CRR) es un componente crítico de una estrategia de continuidad de negocio y recuperación ante desastres (DRP). Esta característica permite realizar restauraciones de datos en una región secundaria emparejada de Azure en cualquier momento, garantizando el acceso a los backups incluso si la región principal sufre una interrupción total o desastre regional. + +**Nota técnica:** Para que la restauración entre regiones sea efectiva, el almacén debe tener configurado el tipo de almacenamiento como `GeoRedundant`. + +## Lógica de la Regla + +La política analiza el recurso `azurerm_recovery_services_vault` evaluando dos condiciones: +1. **Atributo Ausente:** Si no se define explícitamente `cross_region_restore_enabled`, se considera no conforme, ya que la configuración por defecto no garantiza la disponibilidad del dato en la región secundaria. +2. **Configuración Incorrecta:** Si el atributo se establece explícitamente como `false`, se genera una alerta indicando la falta de redundancia operativa para restauraciones. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Configuración de CRR Ausente + +* **Descripción:** El almacén se define sin especificar la política de restauración regional, lo que resulta en la desactivación por defecto de esta medida de resiliencia. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_recovery_services_vault" "fail_missing" { + name = "vault-insecure" + location = "West Europe" + resource_group_name = azurerm_resource_group.example.name + sku = "Standard" + storage_mode_type = "GeoRedundant" + # Falta cross_region_restore_enabled = true + } + ``` +* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_recovery_services_vault`. + +--- + +### Caso 2: CRR Deshabilitado Explícitamente + +* **Descripción:** Se ha configurado el atributo `cross_region_restore_enabled` con el valor `false`, impidiendo la recuperación de desastres en regiones emparejadas. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_recovery_services_vault" "fail_false" { + name = "vault-disabled" + storage_mode_type = "GeoRedundant" + cross_region_restore_enabled = false # <-- Problema detectado + } + ``` +* **Ubicación de la Alerta:** Atributo `cross_region_restore_enabled`. + +## Recurso Involucrado + +* `azurerm_recovery_services_vault` + +## Solución + +Establezca `cross_region_restore_enabled` en `true` y asegúrese de que el `storage_mode_type` sea `GeoRedundant`. + +```terraform +resource "azurerm_recovery_services_vault" "secure_vault" { + name = "vault-resilient" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + sku = "Standard" + storage_mode_type = "GeoRedundant" + + # SOLUCIÓN: Habilitar restauración entre regiones + cross_region_restore_enabled = true +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json new file mode 100644 index 00000000000..5714b398bc0 --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "b7b0bc16-aedc-405e-a27e-cf159c200f1e", + "queryName": "Recovery Services Vault Cross Region Restore Disabled", + "severity": "MEDIUM", + "category": "Backup", + "descriptionText": "Ensures that 'Cross Region Restore' is enabled for Azure Recovery Services Vaults. This feature allows you to restore data in the secondary region, which is essential for business continuity during a primary region disaster.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/recovery_services_vault#cross_region_restore_enabled", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-668", + "descriptionID": "b7b0bc16", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego new file mode 100644 index 00000000000..bb16333f81d --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego @@ -0,0 +1,33 @@ +package Cx + +# REGLA 1: Atributo 'cross_region_restore_enabled' ausente. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_recovery_services_vault[name] + + object.get(vault, "cross_region_restore_enabled", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_recovery_services_vault.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_recovery_services_vault.%s' should have 'cross_region_restore_enabled' set to true", [name]), + "keyActualValue": sprintf("'azurerm_recovery_services_vault.%s' is missing 'cross_region_restore_enabled'", [name]), + } +} + +# REGLA 2: Atributo 'cross_region_restore_enabled' establecido en false. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_recovery_services_vault[name] + + vault.cross_region_restore_enabled == false + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_recovery_services_vault.%s.cross_region_restore_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'cross_region_restore_enabled' should be set to true", + "keyActualValue": "'cross_region_restore_enabled' is set to false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/negative1.tf new file mode 100644 index 00000000000..93b14ef30fd --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/negative1.tf @@ -0,0 +1,8 @@ +resource "azurerm_recovery_services_vault" "pass" { + name = "pass-vault" + location = "West Europe" + resource_group_name = "rg-test" + sku = "Standard" + storage_mode_type = "GeoRedundant" + cross_region_restore_enabled = true +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive1.tf new file mode 100644 index 00000000000..dc1ac3cdc8c --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive1.tf @@ -0,0 +1,7 @@ +resource "azurerm_recovery_services_vault" "fail_omission" { + name = "fail-vault-omission" + location = "West Europe" + resource_group_name = "rg-test" + sku = "Standard" + storage_mode_type = "GeoRedundant" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive2.tf new file mode 100644 index 00000000000..21220fbc5f4 --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive2.tf @@ -0,0 +1,8 @@ +resource "azurerm_recovery_services_vault" "fail_explicit" { + name = "fail-vault-explicit" + location = "West Europe" + resource_group_name = "rg-test" + sku = "Standard" + storage_mode_type = "GeoRedundant" + cross_region_restore_enabled = false +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..ad96799ed4d --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Recovery Services Vault Cross Region Restore Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Recovery Services Vault Cross Region Restore Disabled", + "severity": "MEDIUM", + "line": 7, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/README.md new file mode 100644 index 00000000000..bed1a30d845 --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/README.md @@ -0,0 +1,79 @@ +# Regla KICS: Recovery Services Vault Infrastructure Encryption Disabled + +## Descripción General + +Esta regla de KICS verifica que el **Cifrado de Infraestructura** (`infrastructure_encryption_enabled`) esté habilitado en los almacenes de **Recovery Services Vault**. + +El cifrado de infraestructura proporciona una capa adicional de protección mediante el uso de un segundo algoritmo de cifrado (**Double Encryption**). Mientras que todos los datos en Azure ya están cifrados en reposo, habilitar esta opción asegura que los datos se cifren dos veces utilizando dos algoritmos independientes. Esta configuración es fundamental para organizaciones con requisitos de cumplimiento altamente estrictos que buscan mitigar riesgos ante posibles vulnerabilidades en un único estándar criptográfico. + +## Lógica de la Regla + +La política analiza el recurso `azurerm_recovery_services_vault` validando dos aspectos técnicos: +1. **Bloque de Cifrado:** Verifica la existencia del bloque `encryption`. Si no existe, se asume que no hay doble cifrado. +2. **Cifrado de Infraestructura:** Verifica que el atributo `infrastructure_encryption_enabled` esté explícitamente establecido en `true`. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Bloque de Cifrado Ausente + +* **Descripción:** El almacén no tiene definido el bloque `encryption`, por lo que utiliza únicamente el cifrado predeterminado de Azure sin capas adicionales. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_recovery_services_vault" "fail_missing" { + name = "insecure-vault" + resource_group_name = "rg-prod" + location = "West Europe" + sku = "Standard" + # Falta bloque encryption {} + } + ``` +* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_recovery_services_vault`. + +--- + +### Caso 2: Cifrado de Infraestructura Deshabilitado + +* **Descripción:** El bloque `encryption` existe pero el atributo `infrastructure_encryption_enabled` no está configurado o se encuentra en `false`. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_recovery_services_vault" "fail_disabled" { + name = "vault-vulnerable" + # ... + encryption { + key_id = azurerm_key_vault_key.example.id + infrastructure_encryption_enabled = false + use_system_assigned_identity = true + } + } + ``` +* **Ubicación de la Alerta:** Atributo `infrastructure_encryption_enabled`. + +## Recurso Involucrado + +* `azurerm_recovery_services_vault` + +## Solución + +Para mitigar este riesgo, asegúrese de declarar el bloque `encryption` estableciendo `infrastructure_encryption_enabled` en `true`. + +```terraform +resource "azurerm_recovery_services_vault" "secure_vault" { + name = "secure-recovery-vault" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + sku = "Standard" + + identity { + type = "SystemAssigned" + } + + encryption { + key_id = azurerm_key_vault_key.example.id + infrastructure_encryption_enabled = true + use_system_assigned_identity = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json new file mode 100644 index 00000000000..44dd19a744d --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "95e32d9c-77b5-423a-8746-35ab59a85148", + "queryName": "Recovery Services Vault Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that 'Infrastructure Encryption' (Double Encryption) is enabled for Azure Recovery Services Vaults. This provides a second layer of encryption for data at rest using platform-managed keys.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/recovery_services_vault#infrastructure_encryption_enabled", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-312", + "descriptionID": "95e32d9c", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego new file mode 100644 index 00000000000..bbdfc81beaf --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego @@ -0,0 +1,34 @@ +package Cx + +# REGLA 1: El bloque 'encryption' no está definido. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_recovery_services_vault[name] + + not vault.encryption + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_recovery_services_vault.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_recovery_services_vault.%s' should have an 'encryption' block defined", [name]), + "keyActualValue": sprintf("'azurerm_recovery_services_vault.%s' is missing the 'encryption' block", [name]), + } +} + +# REGLA 2: El atributo 'infrastructure_encryption_enabled' no está en true. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_recovery_services_vault[name] + + vault.encryption + object.get(vault.encryption, "infrastructure_encryption_enabled", false) != true + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_recovery_services_vault.%s.encryption.infrastructure_encryption_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "encryption.infrastructure_encryption_enabled should be set to true", + "keyActualValue": sprintf("encryption.infrastructure_encryption_enabled is set to %v", [object.get(vault.encryption, "infrastructure_encryption_enabled", false)]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/negative1.tf new file mode 100644 index 00000000000..1e10cf5603c --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/negative1.tf @@ -0,0 +1,16 @@ +resource "azurerm_recovery_services_vault" "pass" { + name = "vault-pass" + resource_group_name = "rg" + location = "West Europe" + sku = "Standard" + + identity { + type = "SystemAssigned" + } + + encryption { + key_id = "https://kv.vault.azure.net/keys/key/v1" + infrastructure_encryption_enabled = true + use_system_assigned_identity = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive1.tf new file mode 100644 index 00000000000..51f73d0b5e7 --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive1.tf @@ -0,0 +1,6 @@ +resource "azurerm_recovery_services_vault" "fail_1" { + name = "fail-missing-encryption" + resource_group_name = "rg" + location = "West Europe" + sku = "Standard" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive2.tf new file mode 100644 index 00000000000..2ee8fe240fc --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive2.tf @@ -0,0 +1,12 @@ +resource "azurerm_recovery_services_vault" "fail_2" { + name = "fail-disabled-infrastructure" + resource_group_name = "rg" + location = "West Europe" + sku = "Standard" + + encryption { + key_id = "key-id" + infrastructure_encryption_enabled = false + use_system_assigned_identity = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..098d8633fae --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Recovery Services Vault Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Recovery Services Vault Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "line": 9, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/README.md b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/README.md new file mode 100644 index 00000000000..d243e68a8e5 --- /dev/null +++ b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/README.md @@ -0,0 +1,56 @@ +# Regla KICS: SQL Server TDE Not Encrypted with CMK + +## Descripción General + +Esta regla de KICS asegura que la característica **Transparent Data Encryption (TDE)** de Azure SQL Server esté configurada para utilizar una **clave gestionada por el cliente (Customer-Managed Key - CMK)** almacenada en Azure Key Vault. + +Por defecto, Azure SQL cifra los datos en reposo utilizando una clave gestionada por el servicio (Microsoft). Aunque este método proporciona seguridad base, el uso de CMK ofrece un nivel de control superior indispensable para cumplir con normativas estrictas de seguridad corporativa. Con CMK, la organización asume el control total sobre el ciclo de vida de las claves, permitiendo la rotación, revocación de acceso y auditoría de uso de forma soberana a través de Azure Key Vault. + +## Lógica de la Regla + +La política audita la configuración de Terraform siguiendo estos criterios: +1. **Identificación:** Localiza todos los recursos de tipo `azurerm_mssql_server`. +2. **Vinculación:** Busca si existe un recurso independiente del tipo `azurerm_mssql_server_transparent_data_encryption` vinculado al servidor mediante el atributo `server_id`. +3. **Validación de Clave:** Verifica que dicho recurso tenga definido explícitamente el atributo `key_vault_key_id`. +4. **Alerta:** Si no se encuentra el recurso de cifrado o si falta la referencia a la clave de Key Vault, se genera un hallazgo. + +## Caso de Fallo Detectado + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso Único: Uso de Clave Gestionada por el Servicio (Default) + +* **Descripción:** Se define el servidor SQL pero no se añade el recurso adicional necesario para habilitar el cifrado TDE mediante llaves del cliente, manteniendo el cifrado por defecto de Azure. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_mssql_server" "fail_server" { + name = "insecure-sql-server" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + version = "12.0" + administrator_login = "sqladmin" + administrator_password = "P@ssword123!" + + # Falta el recurso azurerm_mssql_server_transparent_data_encryption + } + ``` +* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_mssql_server`. + +## Recursos Involucrados + +* `azurerm_mssql_server` +* `azurerm_mssql_server_transparent_data_encryption` + +## Solución + +Para mitigar este riesgo, cree un recurso `azurerm_mssql_server_transparent_data_encryption`, vincúlelo al servidor SQL y proporcione la URI de la clave de Azure Key Vault. + +```terraform +resource "azurerm_mssql_server_transparent_data_encryption" "secure_tde" { + server_id = azurerm_mssql_server.example.id + + # SOLUCIÓN: Usar una clave gestionada por el cliente + key_vault_key_id = azurerm_key_vault_key.example.id +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json new file mode 100644 index 00000000000..8047f2f55df --- /dev/null +++ b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "745e82b3-edf5-4606-a5c2-25d8453e7de6", + "queryName": "SQL Server TDE Not Encrypted with CMK", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that Azure SQL Server Transparent Data Encryption (TDE) is configured with a Customer-Managed Key (CMK) stored in Azure Key Vault, rather than the default Service-Managed Key.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mssql_server_transparent_data_encryption", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-326", + "descriptionID": "745e82b3", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego new file mode 100644 index 00000000000..22c9b17da63 --- /dev/null +++ b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego @@ -0,0 +1,32 @@ +package Cx + +has_cmk_tde(doc, server_id) { + tde := doc.resource.azurerm_mssql_server_transparent_data_encryption[_] + check_id(tde.server_id, server_id) + tde.key_vault_key_id +} + +check_id(current, target) { + current == target +} + +check_id(current, target) { + current == sprintf("${%s}", [target]) +} + +# REGLA 1: SQL Server sin configuración de TDE explícita o sin CMK. +CxPolicy[result] { + doc := input.document[i] + server := doc.resource.azurerm_mssql_server[name] + server_id := sprintf("azurerm_mssql_server.%s.id", [name]) + + not has_cmk_tde(doc, server_id) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_mssql_server.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_mssql_server.%s' should have an associated 'azurerm_mssql_server_transparent_data_encryption' resource with 'key_vault_key_id' set", [name]), + "keyActualValue": sprintf("'azurerm_mssql_server.%s' is using Service-Managed Key (default) or lacks TDE resource", [name]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/negative1.tf new file mode 100644 index 00000000000..9d1a96c6668 --- /dev/null +++ b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/negative1.tf @@ -0,0 +1,13 @@ +resource "azurerm_mssql_server" "pass" { + name = "sql-server-pass" + resource_group_name = "rg-test" + location = "West Europe" + version = "12.0" + administrator_login = "sqladmin" + administrator_login_password = "Password123!" +} + +resource "azurerm_mssql_server_transparent_data_encryption" "pass_tde" { + server_id = azurerm_mssql_server.pass.id + key_vault_key_id = "https://kv.vault.azure.net/keys/key/v1" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive1.tf new file mode 100644 index 00000000000..7e5a913fb3e --- /dev/null +++ b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive1.tf @@ -0,0 +1,8 @@ +resource "azurerm_mssql_server" "fail" { + name = "sql-server-fail" + resource_group_name = "rg-test" + location = "West Europe" + version = "12.0" + administrator_login = "sqladmin" + administrator_login_password = "Password123!" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..c6f6f5d4124 --- /dev/null +++ b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "SQL Server TDE Not Encrypted with CMK", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/README.md b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/README.md new file mode 100644 index 00000000000..6dfd2710310 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/README.md @@ -0,0 +1,55 @@ +# Regla KICS: Storage Account Geo-Redundancy Disabled + +## Descripción General + +Esta regla de KICS verifica que las cuentas de almacenamiento de Azure (`azurerm_storage_account`) estén configuradas con **Redundancia Geográfica**. + +La redundancia geográfica es una estrategia de continuidad del negocio fundamental. Al habilitarla, Azure copia los datos de forma asíncrona en una región secundaria situada a cientos de kilómetros de la región principal. Esto garantiza que, ante un desastre regional catastrófico (fallos masivos de red, desastres naturales o cortes de energía en toda una región), los datos permanezcan duraderos y disponibles para su recuperación, minimizando el RPO (objetivo de punto de recuperación) y el RTO (objetivo de tiempo de recuperación). + +## Lógica de la Regla + +La política audita el atributo `account_replication_type` del recurso `azurerm_storage_account`: +1. **Validación de Tipo:** Comprueba si el valor configurado pertenece al grupo de alta disponibilidad regional: `GRS`, `RAGRS`, `GZRS` o `RAGZRS`. +2. **Detección de Riesgo:** Si el valor es `LRS` (Localmente redundante) o `ZRS` (Redundancia de zona), se genera una alerta, ya que estos niveles solo protegen contra fallos de hardware dentro de un centro de datos o zona, pero no contra la pérdida de una región completa. + +## Caso de Fallo Detectado + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso Único: Replicación Local o Zonal (LRS/ZRS) + +* **Descripción:** La cuenta de almacenamiento utiliza un esquema de replicación que no se extiende fuera de la región principal, dejando los datos vulnerables ante desastres regionales. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_storage_account" "fail_storage" { + name = "insecurestorage" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + + # FALLO: Replicación limitada a la región local + account_replication_type = "LRS" + } + ``` +* **Ubicación de la Alerta:** Atributo `account_replication_type`. + +## Recurso Involucrado + +* `azurerm_storage_account` + +## Solución + +Para mitigar este riesgo en entornos de producción, cambie el tipo de replicación a uno que soporte redundancia geográfica, como **GRS**. + +```terraform +resource "azurerm_storage_account" "secure_storage" { + name = "securestorage" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + + # SOLUCIÓN: Habilitar redundancia geográfica + account_replication_type = "GRS" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json new file mode 100644 index 00000000000..7c5d7efb00d --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "56c748b8-9ec8-4f3e-84ac-c9a6992e1b20", + "queryName": "Storage Account Geo-Redundancy Disabled", + "severity": "MEDIUM", + "category": "Availability", + "descriptionText": "Ensures that Azure Storage Accounts use Geo-Redundant Storage (GRS, RAGRS, GZRS, or RAGZRS). This is critical for disaster recovery, ensuring data is durable even in the event of a complete regional outage.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#account_replication_type", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-668", + "descriptionID": "56c748b8", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego new file mode 100644 index 00000000000..daa11248e5c --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego @@ -0,0 +1,21 @@ +package Cx + +geo_redundant_types := {"GRS", "RAGRS", "GZRS", "RAGZRS"} + +# REGLA 1: El tipo de replicación no es Geo-Redundante (ej. es LRS o ZRS). +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + current_type := sa.account_replication_type + + not geo_redundant_types[current_type] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account.%s.account_replication_type", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'account_replication_type' should be 'GRS', 'RAGRS', 'GZRS', or 'RAGZRS'", + "keyActualValue": sprintf("'account_replication_type' is set to '%s'", [current_type]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/negative1.tf new file mode 100644 index 00000000000..01fd017e155 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/negative1.tf @@ -0,0 +1,7 @@ +resource "azurerm_storage_account" "pass" { + name = "storagepass" + resource_group_name = "rg-test" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "GRS" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/positive1.tf new file mode 100644 index 00000000000..40dd592b5df --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/positive1.tf @@ -0,0 +1,7 @@ +resource "azurerm_storage_account" "fail" { + name = "storagefail" + resource_group_name = "rg-test" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..a6c97123f83 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "Storage Account Geo-Redundancy Disabled", + "severity": "MEDIUM", + "line": 6, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/README.md new file mode 100644 index 00000000000..5bc305813ee --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/README.md @@ -0,0 +1,72 @@ +# Regla KICS: Storage Account Infrastructure Encryption Disabled + +## Descripción General + +Esta regla de KICS verifica que el **Cifrado de Infraestructura** (`infrastructure_encryption_enabled`) esté habilitado en los recursos `azurerm_storage_account`. + +Por defecto, Azure Storage cifra todos los datos en reposo mediante el cifrado del lado del servidor (SSE) utilizando claves gestionadas por Microsoft. Sin embargo, habilitar el cifrado de infraestructura proporciona una capa de defensa en profundidad conocida como **Doble Cifrado** (Double Encryption). En este modelo, los datos se cifran dos veces: una a nivel del servicio de almacenamiento y otra a nivel de la infraestructura subyacente, utilizando dos algoritmos de cifrado independientes y claves distintas. Esto protege la información incluso en el caso improbable de que un algoritmo o clave individual se vea comprometido. + +**Nota técnica:** Esta configuración es **inmutable**. Solo se puede habilitar en el momento de la creación de la cuenta de almacenamiento; no es posible activarla posteriormente sin recrear el recurso. + +## Lógica de la Regla + +La política audita el recurso `azurerm_storage_account` evaluando dos escenarios: +1. **Atributo Ausente:** Si no se define explícitamente `infrastructure_encryption_enabled`, KICS asume el valor por defecto (`false`) y genera una alerta sobre el recurso. +2. **Deshabilitado Explícitamente:** Si el atributo está configurado como `false`, se genera una alerta indicando que la protección de doble cifrado no está activa. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Configuración de Doble Cifrado Ausente + +* **Descripción:** Se define la cuenta de almacenamiento sin incluir el parámetro de cifrado de infraestructura, delegando la seguridad únicamente al cifrado simple predeterminado. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_storage_account" "fail_missing" { + name = "storageinsecure" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "LRS" + # Falta infrastructure_encryption_enabled = true + } + ``` +* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_storage_account`. + +--- + +### Caso 2: Cifrado de Infraestructura Deshabilitado Explícitamente + +* **Descripción:** El atributo `infrastructure_encryption_enabled` se ha configurado como `false`, desactivando la capa de seguridad adicional requerida. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_storage_account" "fail_explicit" { + name = "storagedisabled" + # ... + infrastructure_encryption_enabled = false # <-- Problema detectado + } + ``` +* **Ubicación de la Alerta:** Atributo `infrastructure_encryption_enabled`. + +## Recurso Involucrado + +* `azurerm_storage_account` + +## Solución + +Para mitigar este riesgo, establezca `infrastructure_encryption_enabled` en `true` durante la definición inicial de la cuenta de almacenamiento. + +```terraform +resource "azurerm_storage_account" "secure_storage" { + name = "storage-secure" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "GRS" + + # SOLUCIÓN: Habilitar el doble cifrado de infraestructura + infrastructure_encryption_enabled = true +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json new file mode 100644 index 00000000000..4b988f9c413 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "d02793e5-b3b5-4cfa-b379-7a81d5bfe170", + "queryName": "Storage Account Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that 'Infrastructure Encryption' is enabled for Azure Storage Accounts. This provides a second layer of encryption (double encryption) for data at rest, protecting against the compromise of any single encryption algorithm or key.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#infrastructure_encryption_enabled", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-312", + "descriptionID": "d02793e5", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego new file mode 100644 index 00000000000..149bbed7e9f --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego @@ -0,0 +1,33 @@ +package Cx + +# REGLA 1: Atributo 'infrastructure_encryption_enabled' ausente. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + object.get(sa, "infrastructure_encryption_enabled", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have 'infrastructure_encryption_enabled' set to true", [name]), + "keyActualValue": sprintf("'azurerm_storage_account.%s' is missing 'infrastructure_encryption_enabled'", [name]), + } +} + +# REGLA 2: Atributo 'infrastructure_encryption_enabled' establecido en false. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + sa.infrastructure_encryption_enabled == false + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account.%s.infrastructure_encryption_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'infrastructure_encryption_enabled' should be set to true", + "keyActualValue": "'infrastructure_encryption_enabled' is set to false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/negative1.tf new file mode 100644 index 00000000000..1c168bb3be0 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/negative1.tf @@ -0,0 +1,8 @@ +resource "azurerm_storage_account" "pass" { + name = "stpass" + resource_group_name = "rg-test" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" + infrastructure_encryption_enabled = true +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive1.tf new file mode 100644 index 00000000000..acc79de247b --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive1.tf @@ -0,0 +1,7 @@ +resource "azurerm_storage_account" "fail_omission" { + name = "stfailomission" + resource_group_name = "rg-test" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive2.tf new file mode 100644 index 00000000000..4be506a4672 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive2.tf @@ -0,0 +1,8 @@ +resource "azurerm_storage_account" "fail_explicit" { + name = "stfailexplicit" + resource_group_name = "rg-test" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" + infrastructure_encryption_enabled = false +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..4c58ec8ff3a --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Storage Account Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Storage Account Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "line": 7, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/README.md b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/README.md new file mode 100644 index 00000000000..bf0b5dab876 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/README.md @@ -0,0 +1,63 @@ +# Regla KICS: Storage Account ReadOnly Lock Missing + +## Descripción General + +Esta regla de KICS verifica que las cuentas de almacenamiento de Azure (`azurerm_storage_account`) tengan aplicado un **bloqueo de recursos** (`azurerm_management_lock`) configurado específicamente en el nivel **`ReadOnly`**. + +Los bloqueos de Azure Resource Manager (ARM) proporcionan una capa de seguridad adicional que trasciende los permisos de RBAC. Aplicar un bloqueo de tipo `ReadOnly` a una cuenta de almacenamiento garantiza que la configuración del recurso (como las reglas de firewall, los niveles de acceso o la configuración de replicación) no pueda ser modificada ni el recurso eliminado accidentalmente, incluso por administradores. Es una práctica esencial para activos de datos críticos en entornos de producción. + +## Lógica de la Regla + +La política realiza un análisis cruzado entre los recursos de la cuenta de almacenamiento y los bloqueos definidos: +1. **Identificación:** Localiza todas las instancias de `azurerm_storage_account`. +2. **Vinculación:** Busca recursos `azurerm_management_lock` cuyo atributo `scope` referencie al ID del Storage Account. +3. **Validación de Nivel:** Verifica que el atributo `lock_level` sea estrictamente `"ReadOnly"`. +4. **Generación de Hallazgo:** Si el recurso no tiene ningún bloqueo o si los bloqueos existentes tienen un nivel inferior (como `CanNotDelete`), se genera una alerta. + +## Casos de Fallo Detectados + +### Caso 1: Storage Account sin Bloqueo + +* **Descripción:** La cuenta de almacenamiento se ha desplegado sin ninguna restricción de gestión, permitiendo modificaciones accidentales. +* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_storage_account`. + +--- + +### Caso 2: Bloqueo con Nivel Incorrecto + +* **Descripción:** Existe un bloqueo asociado al recurso, pero su nivel es `"CanNotDelete"`, lo cual permite modificaciones en la configuración que la regla busca restringir mediante `"ReadOnly"`. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_management_lock" "fail_lock" { + name = "prevent-deletion" + scope = azurerm_storage_account.example.id + lock_level = "CanNotDelete" # <-- FALLO: Se requiere 'ReadOnly' + } + ``` +* **Ubicación de la Alerta:** Atributo `lock_level` del recurso de bloqueo. + +## Recursos Involucrados + +* `azurerm_storage_account` +* `azurerm_management_lock` + +## Solución + +Añada un recurso `azurerm_management_lock` apuntando al ID de la cuenta de almacenamiento con el nivel `ReadOnly`. + +```terraform +resource "azurerm_storage_account" "secure_sa" { + name = "storage-prod-critical" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "GRS" +} + +# SOLUCIÓN: Aplicar bloqueo ReadOnly +resource "azurerm_management_lock" "sa_readonly_lock" { + name = "critical-storage-lock" + scope = azurerm_storage_account.secure_sa.id + lock_level = "ReadOnly" + notes = "Bloqueo de seguridad para cumplimiento de política de gobernanza" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json new file mode 100644 index 00000000000..99fa66216c4 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "3a716202-a630-4f23-b8ba-2dcbc40e2fa7", + "queryName": "Storage Account ReadOnly Lock Missing", + "severity": "LOW", + "category": "Resource Management", + "descriptionText": "Ensures that Azure Storage Accounts have a Resource Manager lock with 'ReadOnly' level applied. This prevents accidental modification or deletion of the storage account configuration.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/management_lock", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-400", + "descriptionID": "3a716202", + "riskScore": 2.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego new file mode 100644 index 00000000000..560db7a509c --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego @@ -0,0 +1,58 @@ +package Cx + +has_readonly_lock(doc, sa_id) { + l := doc.resource.azurerm_management_lock[_] + check_lock_scope(l.scope, sa_id) + l.lock_level == "ReadOnly" +} + +check_lock_scope(current, target) { + current == target +} + +check_lock_scope(current, target) { + current == sprintf("${%s}", [target]) +} + +# CASO 1: Storage Account totalmente desprotegido (sin bloqueos asociados) +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[sa_name] + sa_id := sprintf("azurerm_storage_account.%s.id", [sa_name]) + + associated_locks := [l | + l := doc.resource.azurerm_management_lock[_] + check_lock_scope(l.scope, sa_id) + ] + count(associated_locks) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account.%s", [sa_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have a 'ReadOnly' lock associated", [sa_name]), + "keyActualValue": sprintf("'azurerm_storage_account.%s' has no locks associated", [sa_name]), + } +} + +# CASO 2: Storage Account con bloqueo incorrecto (nivel distinto a ReadOnly) +CxPolicy[result] { + doc := input.document[i] + lock := doc.resource.azurerm_management_lock[lock_name] + + lock.lock_level != "ReadOnly" + + sa := doc.resource.azurerm_storage_account[sa_name] + sa_id := sprintf("azurerm_storage_account.%s.id", [sa_name]) + check_lock_scope(lock.scope, sa_id) + + not has_readonly_lock(doc, sa_id) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_management_lock.%s.lock_level", [lock_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": sprintf("'azurerm_management_lock.%s.lock_level' should be 'ReadOnly'", [lock_name]), + "keyActualValue": sprintf("'azurerm_management_lock.%s.lock_level' is '%s'", [lock_name, lock.lock_level]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/negative1.tf b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/negative1.tf new file mode 100644 index 00000000000..d1f2a9b1aae --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/negative1.tf @@ -0,0 +1,13 @@ +resource "azurerm_storage_account" "pass" { + name = "stpass" + resource_group_name = "rg-test" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_management_lock" "pass_lock" { + name = "readonly-lock" + scope = azurerm_storage_account.pass.id + lock_level = "ReadOnly" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive1.tf b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive1.tf new file mode 100644 index 00000000000..22d586ce54a --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive1.tf @@ -0,0 +1,7 @@ +resource "azurerm_storage_account" "fail_1" { + name = "stfailnoblocking" + resource_group_name = "rg-test" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive2.tf b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive2.tf new file mode 100644 index 00000000000..60837ce3bc1 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive2.tf @@ -0,0 +1,13 @@ +resource "azurerm_storage_account" "sa_fail_2" { + name = "stfailwronglevel" + resource_group_name = "rg-test" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_management_lock" "fail_lock_level" { + name = "not-readonly" + scope = azurerm_storage_account.sa_fail_2.id + lock_level = "CanNotDelete" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..97fd3418dd5 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Storage Account ReadOnly Lock Missing", + "severity": "LOW", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Storage Account ReadOnly Lock Missing", + "severity": "LOW", + "line": 12, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/README.md b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/README.md new file mode 100644 index 00000000000..9b9b41c70e4 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/README.md @@ -0,0 +1,76 @@ +# Regla KICS: Storage Account Blob Versioning Disabled + +## Descripción General + +Esta regla verifica que la característica de **Versioning** (control de versiones) esté habilitada en los recursos `azurerm_storage_account`. + +El control de versiones de Blobs permite mantener automáticamente versiones anteriores de un objeto cuando este se modifica o elimina. Es una capa de protección fundamental para escenarios de recuperación de datos ante errores humanos, sobreescrituras accidentales o ataques de ransomware, permitiendo restaurar un estado anterior del archivo sin necesidad de recurrir a copias de seguridad externas complejas. + +## Lógica de la Regla + +La política evalúa la configuración en tres niveles de granularidad: +1. **Bloque Ausente:** Si el recurso no tiene definido el bloque `blob_properties`. +2. **Atributo Ausente:** Si existe el bloque pero no se define el parámetro `versioning_enabled`. +3. **Valor Incorrecto:** Si `versioning_enabled` se ha configurado explícitamente como `false`. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Configuración de Bloque Ausente + +* **Descripción:** El recurso no define el bloque `blob_properties`. Por defecto, Azure deshabilita el versionado si no se especifica. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_storage_account" "fail_1" { + name = "storage-insecure-1" + resource_group_name = "rg-prod" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" + + # El bloque blob_properties es inexistente + } + ``` +* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_storage_account`. + +--- + +### Caso 2: Versionado Deshabilitado Explícitamente + +* **Descripción:** Se ha incluido el bloque de propiedades pero el versionado está apagado, lo que impide la recuperación de archivos modificados. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_storage_account" "fail_2" { + name = "storage-insecure-2" + # ... + blob_properties { + versioning_enabled = false # <-- PROBLEMA: Deshabilitado. + } + } + ``` +* **Ubicación de la Alerta:** Línea `versioning_enabled = false`. + +## Recurso Involucrado + +* `azurerm_storage_account` + +## Solución + +Para solucionar este riesgo, asegúrese de incluir el bloque `blob_properties` con el atributo `versioning_enabled` establecido en `true`. + +```terraform +resource "azurerm_storage_account" "secure_storage" { + name = "storage-secure" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "GRS" + + # SOLUCIÓN: Habilitar el control de versiones de blobs + blob_properties { + versioning_enabled = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json new file mode 100644 index 00000000000..88efc35cafb --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "0f437572-8be4-4e05-9f76-dd266d7ad90b", + "queryName": "Storage Account Blob Versioning Disabled", + "severity": "MEDIUM", + "category": "Backup", + "descriptionText": "Ensures that 'Versioning' is enabled for Azure Storage Account Blob services. Blob versioning enables automatic retention of previous versions of an object.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#versioning_enabled", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-226", + "descriptionID": "0f437572", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego new file mode 100644 index 00000000000..70bc0f27b04 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego @@ -0,0 +1,51 @@ +package Cx + +# CASO 1: Falta el bloque 'blob_properties' completo. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + not sa.blob_properties + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have 'blob_properties' defined", [name]), + "keyActualValue": sprintf("'azurerm_storage_account.%s' is missing 'blob_properties'", [name]), + } +} + +# CASO 2: Existe 'blob_properties' pero falta el atributo 'versioning_enabled'. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + sa.blob_properties + + object.get(sa.blob_properties, "versioning_enabled", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account.%s.blob_properties", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "blob_properties.versioning_enabled should be defined and set to true", + "keyActualValue": "blob_properties.versioning_enabled is missing", + } +} + +# CASO 3: 'versioning_enabled' existe pero está explícitamente a false. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + sa.blob_properties.versioning_enabled == false + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account.%s.blob_properties.versioning_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "blob_properties.versioning_enabled should be set to true", + "keyActualValue": "blob_properties.versioning_enabled is set to false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/negative1.tf new file mode 100644 index 00000000000..efc6cad605c --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/negative1.tf @@ -0,0 +1,11 @@ +resource "azurerm_storage_account" "pass" { + name = "stpass" + resource_group_name = "rg-test" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" + + blob_properties { + versioning_enabled = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive1.tf new file mode 100644 index 00000000000..219f4827eb9 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive1.tf @@ -0,0 +1,7 @@ +resource "azurerm_storage_account" "fail_missing_block" { + name = "stfailblock" + resource_group_name = "rg-test" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive2.tf new file mode 100644 index 00000000000..e5d343549ae --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive2.tf @@ -0,0 +1,11 @@ +resource "azurerm_storage_account" "fail_explicit_false" { + name = "stfailexplicit" + resource_group_name = "rg-test" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" + + blob_properties { + change_feed_enabled = false + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive3.tf b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive3.tf new file mode 100644 index 00000000000..ebf179fbecd --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive3.tf @@ -0,0 +1,11 @@ +resource "azurerm_storage_account" "fail_explicit_false" { + name = "stfailexplicit" + resource_group_name = "rg-test" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" + + blob_properties { + versioning_enabled = false + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..19db728ea31 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Storage Account Blob Versioning Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Storage Account Blob Versioning Disabled", + "severity": "MEDIUM", + "line": 8, + "fileName": "positive2.tf" + }, + { + "queryName": "Storage Account Blob Versioning Disabled", + "severity": "MEDIUM", + "line": 9, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/README.md b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/README.md new file mode 100644 index 00000000000..d239d1dd6b5 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/README.md @@ -0,0 +1,46 @@ +# Regla KICS: Storage Blob Service Logging Disabled + +## Descripción General + +Esta regla verifica que el registro de diagnóstico (**Diagnostic Settings**) esté habilitado y configurado íntegramente para el servicio de **Blobs** en las cuentas de almacenamiento de Azure. + +Para garantizar una auditoría completa del plano de datos, es imperativo registrar las tres operaciones fundamentales que permiten rastrear el ciclo de vida de los objetos: +* **StorageRead:** Auditoría de lectura de datos de blobs y metadatos de contenedores. +* **StorageWrite:** Auditoría de subidas, creaciones y modificaciones de blobs. +* **StorageDelete:** Auditoría de eliminaciones de objetos y contenedores. + +## Lógica de la Regla + +La política audita el código Terraform evaluando tres niveles de cumplimiento: +1. **Existencia de Recurso:** Verifica que cada `azurerm_storage_account` tenga un recurso `azurerm_monitor_diagnostic_setting` vinculado a su endpoint de blobs (`/blobServices/default`). +2. **Presencia de Logs:** Alerta si el recurso de diagnóstico existe pero no contiene definiciones de registros (`enabled_log`). +3. **Integridad de Categorías:** Analiza que las categorías `StorageRead`, `StorageWrite` y `StorageDelete` estén presentes. Si el conjunto está incompleto, la alerta apunta directamente al bloque `enabled_log`. + +## Casos de Fallo Detectados + +### Caso 1: Servicio de Blobs sin Diagnostic Settings +* **Ubicación:** `azurerm_storage_account`. + +### Caso 2: Diagnostic Setting sin bloques de Log +* **Ubicación:** `azurerm_monitor_diagnostic_setting`. + +### Caso 3: Auditoría de Blobs Incompleta +* **Descripción:** El bloque de registros no contiene el set completo de categorías (Read, Write y Delete). +* **Ubicación:** Bloque `enabled_log` dentro de `azurerm_monitor_diagnostic_setting`. + +## Recursos Involucrados +* `azurerm_storage_account` +* `azurerm_monitor_diagnostic_setting` + +## Solución + +```terraform +resource "azurerm_monitor_diagnostic_setting" "secure_blob_logging" { + name = "blob-audit-complete" + target_resource_id = "${azurerm_storage_account.example.id}/blobServices/default" + storage_account_id = azurerm_storage_account.log_destination.id + + enabled_log { category = "StorageRead" } + enabled_log { category = "StorageWrite" } + enabled_log { category = "StorageDelete" } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json new file mode 100644 index 00000000000..6433e6ca03d --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "11fa88c0-2064-48ee-8431-953c7d961c71", + "queryName": "Storage Blob Service Logging Disabled", + "severity": "LOW", + "category": "Observability", + "descriptionText": "Ensures that Storage Logging is enabled for the Blob service for 'Read', 'Write', and 'Delete' requests. This provides an audit trail of operations performed on blobs and containers.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#logging", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-778", + "descriptionID": "11fa88c0", + "riskScore": 2.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego new file mode 100644 index 00000000000..1580109acde --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego @@ -0,0 +1,76 @@ +package Cx + +is_target_linked(target, sa_name) { + ref := sprintf("azurerm_storage_account.%s.id", [sa_name]) + contains(target, ref) + contains(target, "blobServices/default") +} + +is_target_linked(target, sa_name) { + ref := sprintf("${azurerm_storage_account.%s.id}", [sa_name]) + contains(target, ref) + contains(target, "blobServices/default") +} + +# CASO 1: La cuenta de almacenamiento no tiene ningún Diagnostic Setting para Blobs. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + not diag_exists_for_sa(doc, name) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have an 'azurerm_monitor_diagnostic_setting' for its blob service", [name]), + "keyActualValue": sprintf("'azurerm_storage_account.%s' does not have diagnostic logging enabled for blobs", [name]), + } +} + +diag_exists_for_sa(doc, sa_name) { + diag := doc.resource.azurerm_monitor_diagnostic_setting[_] + is_target_linked(diag.target_resource_id, sa_name) +} + +# CASO 2: El Diagnostic Setting existe pero no tiene ningún bloque 'enabled_log'. +CxPolicy[result] { + doc := input.document[i] + diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] + + contains(diag.target_resource_id, "blobServices/default") + not diag.enabled_log + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_monitor_diagnostic_setting.%s", [diag_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "Diagnostic Setting should have 'enabled_log' blocks defined", + "keyActualValue": "Diagnostic Setting has no 'enabled_log' blocks", + } +} + +# CASO 3: El Diagnostic Setting tiene bloques 'enabled_log' pero el conjunto está incompleto. +CxPolicy[result] { + doc := input.document[i] + diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] + + contains(diag.target_resource_id, "blobServices/default") + diag.enabled_log + + required_categories := {"StorageRead", "StorageWrite", "StorageDelete"} + present_categories := {cat | + log := diag.enabled_log[_] + cat := log.category + } + + not count(required_categories - present_categories) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_monitor_diagnostic_setting.%s.enabled_log", [diag_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "All required log categories (StorageRead, StorageWrite, StorageDelete) should be present", + "keyActualValue": "One or more required log categories are missing in the 'enabled_log' configuration", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/negative1.tf new file mode 100644 index 00000000000..13a3e1790f3 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/negative1.tf @@ -0,0 +1,17 @@ +resource "azurerm_storage_account" "pass" { + name = "st-pass" + resource_group_name = "rg" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_monitor_diagnostic_setting" "pass_diag" { + name = "complete-diag" + target_resource_id = "${azurerm_storage_account.pass.id}/blobServices/default" + storage_account_id = "target" + + enabled_log { category = "StorageRead" } + enabled_log { category = "StorageWrite" } + enabled_log { category = "StorageDelete" } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive1.tf new file mode 100644 index 00000000000..ea0d8402fd3 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive1.tf @@ -0,0 +1,7 @@ +resource "azurerm_storage_account" "fail_none" { + name = "st-no-blob-diag" + resource_group_name = "rg" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive2.tf new file mode 100644 index 00000000000..7c2838bfa7d --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive2.tf @@ -0,0 +1,6 @@ +resource "azurerm_monitor_diagnostic_setting" "fail_no_logs" { + name = "empty-diag" + target_resource_id = "${azurerm_storage_account.example.id}/blobServices/default" + storage_account_id = "id" + # enabled_log bloque ausente +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive3.tf b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive3.tf new file mode 100644 index 00000000000..d595f8bf0b2 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive3.tf @@ -0,0 +1,10 @@ +resource "azurerm_monitor_diagnostic_setting" "fail_partial" { + name = "partial-diag" + target_resource_id = "${azurerm_storage_account.example.id}/blobServices/default" + storage_account_id = "id" + + enabled_log { + category = "StorageRead" + } + # Faltan Write y Delete. Solo debe saltar 1 vez. +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..77b0bab39ad --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Storage Blob Service Logging Disabled", + "severity": "LOW", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Storage Blob Service Logging Disabled", + "severity": "LOW", + "line": 1, + "fileName": "positive2.tf" + }, + { + "queryName": "Storage Blob Service Logging Disabled", + "severity": "LOW", + "line": 6, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/README.md b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/README.md new file mode 100644 index 00000000000..c09ad4074f5 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/README.md @@ -0,0 +1,65 @@ +# Regla KICS: Storage Immutability Policy Not Locked + +## Descripción General + +Esta regla verifica que las políticas de inmutabilidad (`azurerm_storage_container_immutability_policy`) aplicadas a los contenedores de Azure Storage estén configuradas en estado **Bloqueado** (`locked = true`). + +Las políticas de inmutabilidad permiten que los datos se almacenen en un formato **WORM** (Write Once, Read Many). En el contexto de control de acceso y protección de datos, existen dos estados críticos: +* **Unlocked (Mutable):** La política protege los datos contra borrado o modificación, pero la política en sí puede ser eliminada o modificada por usuarios con altos privilegios. Es un estado transitorio y no garantiza la inalterabilidad a largo plazo. +* **Locked (Inmutable):** Una vez bloqueada, la política se vuelve irreversible; no puede ser eliminada y el periodo de retención solo puede aumentarse. Este estado es un control de integridad estricto que garantiza que ni siquiera un administrador pueda eliminar los datos antes de tiempo. + +## Lógica de la Regla + +La regla audita los recursos `azurerm_storage_container_immutability_policy` evaluando dos condiciones de control: +1. **Omisión del Atributo:** Si no se define el atributo `locked`, Azure asume por defecto el estado "Unlocked", permitiendo que la protección sea removida. +2. **Valor Incorrecto:** Si el atributo `locked` se establece explícitamente en `false`. + +## Casos de Fallo Detectados + +### Caso 1: Atributo de Bloqueo Ausente + +* **Descripción:** Se define una política de retención pero no se especifica si debe estar bloqueada. Por defecto, Azure la crea en estado "Unlocked". +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_storage_container_immutability_policy" "fail_missing" { + storage_container_resource_manager_id = azurerm_storage_container.example.id + retention_period_in_days = 365 + # Falta locked = true + } + ``` +* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_storage_container_immutability_policy`. + +--- + +### Caso 2: Política Mutable (Unlocked) + +* **Descripción:** El atributo `locked` se establece explícitamente en `false`, lo que permite que la política de inmutabilidad sea eliminable por usuarios autorizados. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_storage_container_immutability_policy" "fail_explicit" { + storage_container_resource_manager_id = azurerm_storage_container.example.id + retention_period_in_days = 730 + locked = false # <-- PROBLEMA DETECTADO + } + ``` +* **Ubicación de la Alerta:** Atributo `locked`. + +## Recurso Involucrado + +* `azurerm_storage_container_immutability_policy` + +## Solución + +Establezca el atributo `locked` en `true` para asegurar que el control de integridad de los datos sea permanente y cumpla con los requisitos WORM. + +> [!WARNING] +> **Advertencia Crítica:** Una vez que una política se bloquea en Azure, **no puede eliminarse**. Solo podrá borrar el contenedor una vez que el periodo de retención de todos los objetos haya expirado. Valide cuidadosamente los días de retención antes de aplicar este cambio en producción. + +```terraform +resource "azurerm_storage_container_immutability_policy" "secure_policy" { + storage_container_resource_manager_id = azurerm_storage_container.example.id + retention_period_in_days = 365 + + # SOLUCIÓN: Bloqueo de política habilitado para integridad WORM + locked = true +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json new file mode 100644 index 00000000000..eaf61fafe48 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "9b959753-3a9b-41e7-82b2-28bef91e6b53", + "queryName": "Storage Immutability Policy Not Locked", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that the Immutability Policy for Azure Storage Containers is set to 'Locked'. An unlocked policy can be removed or modified, failing to provide true WORM (Write Once, Read Many) compliance for business-critical data.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_container_immutability_policy#locked", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-284", + "descriptionID": "9b959753", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego new file mode 100644 index 00000000000..233dc06fe1c --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego @@ -0,0 +1,33 @@ +package Cx + +# REGLA 1: El atributo 'locked' no está definido (Default es false/unlocked). +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.azurerm_storage_container_immutability_policy[name] + + object.get(policy, "locked", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_container_immutability_policy.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_storage_container_immutability_policy.%s' should have 'locked' set to true", [name]), + "keyActualValue": sprintf("'azurerm_storage_container_immutability_policy.%s' is missing 'locked' attribute (default is false)", [name]), + } +} + +# REGLA 2: El atributo 'locked' está explícitamente a false. +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.azurerm_storage_container_immutability_policy[name] + + policy.locked == false + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_container_immutability_policy.%s.locked", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'locked' should be set to true", + "keyActualValue": "'locked' is set to false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/negative1.tf b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/negative1.tf new file mode 100644 index 00000000000..24a49a6b0a9 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/negative1.tf @@ -0,0 +1,5 @@ +resource "azurerm_storage_container_immutability_policy" "pass" { + storage_container_resource_manager_id = "some-resource-id" + immutability_period_in_days = 90 + locked = true +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive1.tf b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive1.tf new file mode 100644 index 00000000000..f245a916668 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive1.tf @@ -0,0 +1,4 @@ +resource "azurerm_storage_container_immutability_policy" "fail_omission" { + storage_container_resource_manager_id = "some-resource-id" + immutability_period_in_days = 90 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive2.tf b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive2.tf new file mode 100644 index 00000000000..65f0fe13e6e --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive2.tf @@ -0,0 +1,5 @@ +resource "azurerm_storage_container_immutability_policy" "fail_explicit" { + storage_container_resource_manager_id = "some-resource-id" + immutability_period_in_days = 90 + locked = false +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive_expected_result.json new file mode 100644 index 00000000000..3559388eb05 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Storage Immutability Policy Not Locked", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Storage Immutability Policy Not Locked", + "severity": "MEDIUM", + "line": 4, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/README.md b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/README.md new file mode 100644 index 00000000000..1304966919e --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/README.md @@ -0,0 +1,62 @@ +# Regla KICS: Critical Data Storage CMK (Manual) + +## Descripción General + +Esta regla identifica cuentas de almacenamiento de Azure (`azurerm_storage_account`) que utilizan cifrado gestionado por Microsoft (**Platform-Managed Keys**). + +El cifrado en reposo es automático en Azure, pero el uso de claves gestionadas por la plataforma no siempre es suficiente para cumplir con normativas de soberanía de datos o requisitos de seguridad de datos críticos. Esta regla actúa como un control de **auditoría manual**: identifica recursos sin **Customer-Managed Keys (CMK)** para que el equipo de seguridad valide si los datos contenidos (financieros, PII, secretos industriales) requieren que la organización posea y gestione las claves de cifrado en su propio Key Vault. + +## Lógica de la Regla + +La política audita el recurso `azurerm_storage_account` evaluando dos escenarios: +1. **Ausencia de Configuración CMK:** Si el bloque `customer_managed_key` no está presente, la cuenta utiliza las claves por defecto de Azure. +2. **Configuración Incompleta:** Si el bloque `customer_managed_key` existe pero no define el atributo `key_vault_key_id`, el cifrado CMK no se está aplicando efectivamente. + +## Casos de Fallo Detectados + +### Caso 1: Revisión de Sensibilidad de Datos Requerida (Cifrado Default) + +* **Descripción:** La cuenta utiliza el cifrado base de Azure. Se requiere validación manual para determinar si la criticidad de los datos exige el paso a CMK. +* **Ubicación de la Alerta:** Recurso `azurerm_storage_account`. + +### Caso 2: Bloque CMK sin Clave Asociada + +* **Descripción:** Se ha declarado el bloque de claves gestionadas por el cliente pero se ha omitido el identificador de la clave criptográfica. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_storage_account" "fail_incomplete" { + name = "stincomplete" + # ... + customer_managed_key { + user_assigned_identity_id = azurerm_user_assigned_identity.example.id + # key_vault_key_id es opcional en el esquema pero necesario para CMK + } + } + ``` +* **Ubicación de la Alerta:** Bloque `customer_managed_key`. + +## Recurso Involucrado + +* `azurerm_storage_account` + +## Solución + +Si tras la revisión manual se confirma que los datos son críticos, implemente CMK vinculando una clave de Azure Key Vault. + +```terraform +resource "azurerm_storage_account" "secure_critical" { + name = "stcriticaldata" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "GRS" + + identity { + type = "SystemAssigned" + } + + customer_managed_key { + # SOLUCIÓN: Definir explícitamente la clave de Key Vault + key_vault_key_id = azurerm_key_vault_key.example.id + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json new file mode 100644 index 00000000000..0c21a11ee0b --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "20fcb3ef-4524-4d45-baa9-60b0eb229beb", + "queryName": "Critical Data Storage CMK (Manual)", + "severity": "INFO", + "category": "Encryption", + "descriptionText": "Identifies Storage Accounts using default Platform-Managed Keys. If these accounts store business-critical or sensitive data, they must be encrypted using Customer-Managed Keys (CMK). Manual verification of data sensitivity is required.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#customer_managed_key", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-312", + "descriptionID": "20fcb3ef", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego new file mode 100644 index 00000000000..e888549ca7b --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego @@ -0,0 +1,34 @@ +package Cx + +# REGLA 1: El bloque 'customer_managed_key' no existe. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + not sa.customer_managed_key + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should use CMK if hosting critical data (Manual Verification)", [name]), + "keyActualValue": sprintf("'azurerm_storage_account.%s' is using Platform-Managed Keys", [name]), + } +} + +# REGLA 2: El bloque existe pero el atributo 'key_vault_key_id' no está definido. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + sa.customer_managed_key + object.get(sa.customer_managed_key, "key_vault_key_id", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account.%s.customer_managed_key", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "If 'customer_managed_key' block is defined, it should include 'key_vault_key_id' for CMK encryption", + "keyActualValue": "'key_vault_key_id' is not defined within the 'customer_managed_key' block", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/negative1.tf b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/negative1.tf new file mode 100644 index 00000000000..39bd87c0f6e --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/negative1.tf @@ -0,0 +1,16 @@ +resource "azurerm_storage_account" "pass" { + name = "st-pass-cmk" + resource_group_name = "rg" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" + + identity { + type = "SystemAssigned" + } + + customer_managed_key { + key_vault_key_id = "https://kv.vault.azure.net/keys/key/v1" + user_assigned_identity_id = "some-id" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive1.tf b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive1.tf new file mode 100644 index 00000000000..471c97fbe07 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive1.tf @@ -0,0 +1,7 @@ +resource "azurerm_storage_account" "fail_1" { + name = "st-no-cmk-block" + resource_group_name = "rg" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive2.tf b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive2.tf new file mode 100644 index 00000000000..b774263629d --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive2.tf @@ -0,0 +1,11 @@ +resource "azurerm_storage_account" "fail_2" { + name = "st-block-no-id" + resource_group_name = "rg" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" + + customer_managed_key { + user_assigned_identity_id = "some-id" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..3c78101dd5c --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Critical Data Storage CMK (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Critical Data Storage CMK (Manual)", + "severity": "INFO", + "line": 8, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/README.md b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/README.md new file mode 100644 index 00000000000..3fc500b38a8 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/README.md @@ -0,0 +1,93 @@ +# Regla KICS: Storage Queue Service Logging Disabled + +## Descripción General + +Esta regla verifica que el **Logging de Almacenamiento** (Storage Analytics Logging) esté habilitado para el servicio de **Colas (Queue Service)** en las cuentas de almacenamiento de Azure. + +El registro de auditoría es un componente fundamental de la observabilidad. Permite rastrear la actividad detallada en el plano de datos, capturando quién y cuándo interactuó con los mensajes de la cola. La política valida que se registren las siguientes operaciones: +* **Read (Lectura):** Operaciones como la visualización o extracción de mensajes. +* **Write (Escritura):** Operaciones de inserción o actualización de mensajes. +* **Delete (Borrado):** Operaciones de eliminación de mensajes o vaciado de colas. + +Sin esta configuración, las organizaciones pierden la trazabilidad necesaria para investigar comportamientos anómalos o fugas de información a través del servicio de mensajería. + +## Lógica de la Regla + +La política audita tanto la configuración embebida en la cuenta de almacenamiento como el recurso específico de propiedades: +1. **Identificación de Atributos:** Busca la presencia de `queue_properties` en el recurso principal o instancias del recurso independiente. +2. **Validación de Auditoría:** Asegura la existencia del bloque `logging`. +3. **Verificación de Acciones:** Comprueba que `read`, `write` y `delete` estén configurados explícitamente como `true`. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Logging Embebido Ausente + +* **Descripción:** Se definen propiedades de cola en la cuenta de almacenamiento pero no se incluye la configuración de registro. +* **Ubicación de la Alerta:** Bloque `queue_properties` del recurso `azurerm_storage_account`. + +--- + +### Caso 2: Configuración Embebida Incorrecta + +* **Descripción:** El bloque de registro existe en la cuenta de almacenamiento pero alguna de las acciones críticas está desactivada. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "azurerm_storage_account" "fail_logging" { + # ... + queue_properties { + logging { + read = false # <-- PROBLEMA + write = true + delete = true + version = "1.0" + } + } + } + ``` +* **Ubicación de la Alerta:** Atributo `logging` del recurso `azurerm_storage_account`. + +--- + +### Caso 3: Recurso Standalone sin Logging + +* **Descripción:** Se utiliza el recurso `azurerm_storage_account_queue_properties` pero se omite completamente el bloque de registro. +* **Ubicación de la Alerta:** Recurso `azurerm_storage_account_queue_properties`. + +--- + +### Caso 4: Recurso Standalone con Configuración Incorrecta + +* **Descripción:** El recurso independiente de propiedades tiene el bloque de registro, pero con acciones deshabilitadas. +* **Ubicación de la Alerta:** Atributo `logging` del recurso `azurerm_storage_account_queue_properties`. + +## Recursos Involucrados + +* `azurerm_storage_account` +* `azurerm_storage_account_queue_properties` + +## Solución + +Habilite el registro para todas las operaciones (`read`, `write`, `delete`) dentro de la configuración del servicio de colas. + +```terraform +resource "azurerm_storage_account" "secure_queue" { + name = "stsecurequeue" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "LRS" + + queue_properties { + logging { + read = true + write = true + delete = true + version = "1.0" + retention_policy_days = 30 + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json new file mode 100644 index 00000000000..24c682371b3 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "cddbdd74-3736-4aec-ba57-43b4db315bc2", + "queryName": "Storage Queue Service Logging Disabled", + "severity": "LOW", + "category": "Observability", + "descriptionText": "Ensures that Storage Logging is enabled for the Queue service for 'Read', 'Write', and 'Delete' requests. This provides an audit trail of operations performed on the queues.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#logging", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-778", + "descriptionID": "cddbdd74", + "riskScore": 2.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego new file mode 100644 index 00000000000..0c5fbe8a745 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego @@ -0,0 +1,74 @@ +package Cx + +is_logging_valid(logging) { + logging.read == true + logging.write == true + logging.delete == true +} + +# CASO 1: Bloque 'logging' ausente en 'queue_properties' de azurerm_storage_account. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + sa.queue_properties + not sa.queue_properties.logging + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account.%s.queue_properties", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "queue_properties.logging should be defined with read, write, and delete enabled", + "keyActualValue": "queue_properties.logging is missing", + } +} + +# CASO 2: Configuración de 'logging' incorrecta en azurerm_storage_account. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + logging := sa.queue_properties.logging + not is_logging_valid(logging) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account.%s.queue_properties.logging", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "logging should have read, write, and delete set to true", + "keyActualValue": "logging has one or more required actions (read, write, delete) disabled", + } +} + +# CASO 3: Bloque 'logging' ausente en el recurso azurerm_storage_account_queue_properties. +CxPolicy[result] { + doc := input.document[i] + props := doc.resource.azurerm_storage_account_queue_properties[name] + + not props.logging + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account_queue_properties.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "logging block should be defined in queue properties", + "keyActualValue": "logging block is missing", + } +} + +# CASO 4: Configuración de 'logging' incorrecta en azurerm_storage_account_queue_properties. +CxPolicy[result] { + doc := input.document[i] + props := doc.resource.azurerm_storage_account_queue_properties[name] + + logging := props.logging + not is_logging_valid(logging) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account_queue_properties.%s.logging", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "logging should have read, write, and delete set to true", + "keyActualValue": "logging is missing one or more required actions", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/negative1.tf new file mode 100644 index 00000000000..ee304ada58b --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/negative1.tf @@ -0,0 +1,17 @@ +resource "azurerm_storage_account" "pass_inline" { + name = "stpassinline" + resource_group_name = "rg" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" + + queue_properties { + logging { + read = true + write = true + delete = true + version = "1.0" + retention_policy_days = 7 + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/negative2.tf b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/negative2.tf new file mode 100644 index 00000000000..d479376aa5a --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/negative2.tf @@ -0,0 +1,19 @@ +resource "azurerm_storage_account" "base" { + name = "stbase" + resource_group_name = "rg" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_storage_account_queue_properties" "pass_standalone" { + storage_account_id = azurerm_storage_account.base.id + + logging { + read = true + write = true + delete = true + version = "1.0" + retention_policy_days = 10 + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive1.tf new file mode 100644 index 00000000000..aa4a19e1192 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive1.tf @@ -0,0 +1,11 @@ +resource "azurerm_storage_account" "fail_1" { + name = "stfail1" + resource_group_name = "rg" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" + + queue_properties { + # Falta bloque logging + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive2.tf new file mode 100644 index 00000000000..61cd3bf4219 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive2.tf @@ -0,0 +1,16 @@ +resource "azurerm_storage_account" "fail_2" { + name = "stfail2" + resource_group_name = "rg" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" + + queue_properties { + logging { + read = true + write = false + delete = true + version = "1.0" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive3.tf b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive3.tf new file mode 100644 index 00000000000..97b7aed369b --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive3.tf @@ -0,0 +1,3 @@ +resource "azurerm_storage_account_queue_properties" "fail_3" { + storage_account_id = "some-id" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive4.tf b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive4.tf new file mode 100644 index 00000000000..218bdef5585 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive4.tf @@ -0,0 +1,9 @@ +resource "azurerm_storage_account_queue_properties" "fail_4" { + storage_account_id = "some-id" + logging { + read = false + write = true + delete = true + version = "1.0" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..253c872e665 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive_expected_result.json @@ -0,0 +1,26 @@ +[ + { + "queryName": "Storage Queue Service Logging Disabled", + "severity": "LOW", + "line": 8, + "fileName": "positive1.tf" + }, + { + "queryName": "Storage Queue Service Logging Disabled", + "severity": "LOW", + "line": 9, + "fileName": "positive2.tf" + }, + { + "queryName": "Storage Queue Service Logging Disabled", + "severity": "LOW", + "line": 1, + "fileName": "positive3.tf" + }, + { + "queryName": "Storage Queue Service Logging Disabled", + "severity": "LOW", + "line": 3, + "fileName": "positive4.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/README.md b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/README.md new file mode 100644 index 00000000000..ee83e7ad654 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/README.md @@ -0,0 +1,52 @@ +# Regla KICS: Storage Table Service Logging Disabled + +## Descripción General + +Esta regla verifica que el registro de diagnóstico (**Diagnostic Settings**) esté habilitado y configurado íntegramente para el servicio de **Tablas (Table Service)** en las cuentas de almacenamiento de Azure. + +La auditoría de las tablas NoSQL de Azure Storage permite capturar telemetría sobre quién accede y modifica los datos almacenados. La política asegura que se capturen las tres categorías de operaciones esenciales para una trazabilidad completa: +* **StorageRead:** Auditoría de consultas de entidades y lectura de metadatos de tablas. +* **StorageWrite:** Auditoría de inserciones, actualizaciones y "upserts" de datos. +* **StorageDelete:** Auditoría de eliminaciones de entidades o de la estructura de la tabla. + +Sin estos registros activos, las organizaciones carecen de la telemetría necesaria para identificar accesos no autorizados a datos sensibles o investigar errores en la manipulación de registros NoSQL. + +## Lógica de la Regla + +La política audita el código Terraform evaluando tres niveles de cumplimiento: +1. **Existencia de Recurso:** Verifica que cada `azurerm_storage_account` tenga un recurso `azurerm_monitor_diagnostic_setting` vinculado a su endpoint de tablas (`/tableServices/default`). +2. **Presencia de Logs:** Alerta si el recurso de diagnóstico existe pero el bloque `enabled_log` está ausente. +3. **Integridad de Categorías:** Analiza que las categorías `StorageRead`, `StorageWrite` y `StorageDelete` estén presentes simultáneamente. Si el conjunto está incompleto, la alerta apunta directamente al bloque `enabled_log`. + +## Casos de Fallo Detectados + +### Caso 1: Servicio de Tablas sin Diagnostic Settings +* **Descripción:** La cuenta de almacenamiento no tiene configurado ningún destino de registro para tablas. +* **Ubicación:** `azurerm_storage_account`. + +### Caso 2: Diagnostic Setting sin bloques de Log +* **Descripción:** El recurso de diagnóstico existe pero la configuración de registros está vacía. +* **Ubicación:** `azurerm_monitor_diagnostic_setting`. + +### Caso 3: Auditoría de Tablas Incompleta +* **Descripción:** Faltan una o más categorías críticas en la configuración de logs. +* **Ubicación:** Bloque `enabled_log` dentro de `azurerm_monitor_diagnostic_setting`. + +## Recursos Involucrados +* `azurerm_storage_account` +* `azurerm_monitor_diagnostic_setting` + +## Solución + +Configure un Diagnostic Setting completo para el servicio de tablas. + +```terraform +resource "azurerm_monitor_diagnostic_setting" "secure_table_logging" { + name = "table-audit-complete" + target_resource_id = "${azurerm_storage_account.example.id}/tableServices/default" + storage_account_id = azurerm_storage_account.logs.id + + enabled_log { category = "StorageRead" } + enabled_log { category = "StorageWrite" } + enabled_log { category = "StorageDelete" } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json new file mode 100644 index 00000000000..7ab0ddb59aa --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "0d29e3cf-0033-4ca6-9b97-fa3e6c4d25b8", + "queryName": "Storage Table Service Logging Disabled", + "severity": "LOW", + "category": "Observability", + "descriptionText": "Ensures that Storage Logging is enabled for the Table service for 'Read', 'Write', and 'Delete' requests. This provides an audit trail of operations performed on NoSQL tables within the storage account.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#logging", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "CWE-778", + "descriptionID": "0d29e3cf", + "riskScore": 2.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego new file mode 100644 index 00000000000..0def7c4add9 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego @@ -0,0 +1,76 @@ +package Cx + +is_target_linked(target, sa_name) { + ref := sprintf("azurerm_storage_account.%s.id", [sa_name]) + contains(target, ref) + contains(target, "tableServices/default") +} + +is_target_linked(target, sa_name) { + ref := sprintf("${azurerm_storage_account.%s.id}", [sa_name]) + contains(target, ref) + contains(target, "tableServices/default") +} + +# CASO 1: La cuenta de almacenamiento no tiene ningún Diagnostic Setting para Tablas. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + not diag_exists_for_sa(doc, name) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_storage_account.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have an 'azurerm_monitor_diagnostic_setting' for its table service", [name]), + "keyActualValue": sprintf("'azurerm_storage_account.%s' does not have diagnostic logging enabled for tables", [name]), + } +} + +diag_exists_for_sa(doc, sa_name) { + diag := doc.resource.azurerm_monitor_diagnostic_setting[_] + is_target_linked(diag.target_resource_id, sa_name) +} + +# CASO 2: El Diagnostic Setting existe pero no tiene ningún bloque 'enabled_log'. +CxPolicy[result] { + doc := input.document[i] + diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] + + contains(diag.target_resource_id, "tableServices/default") + not diag.enabled_log + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_monitor_diagnostic_setting.%s", [diag_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "Diagnostic Setting should have 'enabled_log' blocks defined", + "keyActualValue": "Diagnostic Setting has no 'enabled_log' blocks", + } +} + +# CASO 3: El Diagnostic Setting tiene bloques 'enabled_log' pero el conjunto está incompleto. +CxPolicy[result] { + doc := input.document[i] + diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] + + contains(diag.target_resource_id, "tableServices/default") + diag.enabled_log + + required_categories := {"StorageRead", "StorageWrite", "StorageDelete"} + present_categories := {cat | + log := diag.enabled_log[_] + cat := log.category + } + + not count(required_categories - present_categories) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.azurerm_monitor_diagnostic_setting.%s.enabled_log", [diag_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "All required log categories (StorageRead, StorageWrite, StorageDelete) should be present", + "keyActualValue": "One or more required log categories are missing in the 'enabled_log' configuration for Table service", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/negative1.tf new file mode 100644 index 00000000000..f426550f82b --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/negative1.tf @@ -0,0 +1,17 @@ +resource "azurerm_storage_account" "pass" { + name = "st-table-pass" + resource_group_name = "rg" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_monitor_diagnostic_setting" "pass_table_diag" { + name = "complete-table-diag" + target_resource_id = "${azurerm_storage_account.pass.id}/tableServices/default" + storage_account_id = "target" + + enabled_log { category = "StorageRead" } + enabled_log { category = "StorageWrite" } + enabled_log { category = "StorageDelete" } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive1.tf new file mode 100644 index 00000000000..45c4a09dfc7 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive1.tf @@ -0,0 +1,7 @@ +resource "azurerm_storage_account" "fail_none" { + name = "st-no-table-diag" + resource_group_name = "rg" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive2.tf new file mode 100644 index 00000000000..b7399c3f233 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive2.tf @@ -0,0 +1,6 @@ +resource "azurerm_monitor_diagnostic_setting" "fail_no_logs" { + name = "no-logs-diag" + target_resource_id = "${azurerm_storage_account.example.id}/tableServices/default" + storage_account_id = "id" + # No hay bloques enabled_log +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive3.tf b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive3.tf new file mode 100644 index 00000000000..ed9882e5258 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive3.tf @@ -0,0 +1,18 @@ +resource "azurerm_storage_account" "example" { + name = "st-table-partial" + resource_group_name = "rg" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} + +resource "azurerm_monitor_diagnostic_setting" "fail_partial" { + name = "partial-table-diag" + target_resource_id = "${azurerm_storage_account.example.id}/tableServices/default" + storage_account_id = "target" + + # Faltan categorías de log + enabled_log { + category = "StorageRead" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..b853eeccf65 --- /dev/null +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Storage Table Service Logging Disabled", + "severity": "LOW", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Storage Table Service Logging Disabled", + "severity": "LOW", + "line": 1, + "fileName": "positive2.tf" + }, + { + "queryName": "Storage Table Service Logging Disabled", + "severity": "LOW", + "line": 15, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/README.md b/assets/queries/terraform/gcp/gcp_access_approval_disabled/README.md new file mode 100644 index 00000000000..dfa9087e47e --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/README.md @@ -0,0 +1,50 @@ +# Regla KICS: GCP Access Approval Disabled + +## Descripción General + +Esta regla de severidad **MEDIA** audita el cumplimiento del control de acceso de terceros en **Google Cloud (GCP)** para los recursos `google_project`. + +**Access Approval** es un control de seguridad avanzado que permite a las organizaciones establecer un paso de aprobación explícito antes de que el personal de Google (Ingeniería o Soporte) pueda acceder a los datos de sus clientes. Mientras que Google cifra los datos por defecto y restringe el acceso mediante políticas internas, Access Approval otorga al cliente la soberanía final: cualquier intento de acceso genera una solicitud por correo electrónico o mediante Cloud Pub/Sub que el cliente debe aprobar manualmente. + +Sin esta configuración, se asume que el personal de Google puede acceder a los recursos para fines de soporte técnico bajo los términos estándar del contrato, lo que puede no ser suficiente para empresas bajo regulaciones estrictas. + +## Lógica de la Regla + +La política realiza dos validaciones en el código Terraform: +1. **Existencia de la Configuración:** Detecta si un `google_project` carece de un recurso `google_access_approval_project_settings` que lo gestione. +2. **Inscripción de Servicios:** Verifica que, de existir la configuración, esta incluya al menos un bloque `enrolled_services`. Un recurso de configuración sin servicios inscritos no protege activamente ningún producto de GCP. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Proyecto sin Access Approval +* **Descripción:** Se provisiona un proyecto en GCP pero no se implementa el flujo de aprobación de acceso de Google. +* **Ubicación de la Alerta:** Bloque del recurso `google_project`. + +### Caso 2: Configuración de Servicios Ausente +* **Descripción:** Se define el recurso de configuración de Access Approval pero se deja vacío el bloque de servicios protegidos. +* **Ubicación de la Alerta:** Recurso `google_access_approval_project_settings`. + +## Recursos Involucrados + +* `google_project` +* `google_access_approval_project_settings` + +## Solución + +Defina el recurso de configuración y asegúrese de inscribir los servicios deseados (o `all` para una cobertura total). + +```terraform +resource "google_access_approval_project_settings" "compliant_settings" { + project_id = google_project.my_secure_project.project_id + + enrolled_services { + cloud_product = "all" # Protege todos los productos compatibles + enrollment_level = "BLOCK_ALL" + } + + notification_emails = ["security-team@tu-empresa.com"] +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json new file mode 100644 index 00000000000..64cbcb48dff --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "d7df9989-f87a-45cb-80ea-d4d20e3d4530", + "queryName": "GCP Access Approval Disabled", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that Access Approval is enabled for the GCP Project. Access Approval allows you to approve or deny access to your data by Google support and engineering personnel.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/access_approval_project_settings", + "platform": "Terraform", + "descriptionID": "d7df9989", + "cloudProvider": "gcp", + "cwe": "CWE-284", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego b/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego new file mode 100644 index 00000000000..f6a7dfce92f --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego @@ -0,0 +1,38 @@ +package Cx + +# CASO 1: Proyecto sin configuración de Access Approval. +CxPolicy[result] { + doc := input.document[i] + project := doc.resource.google_project[name] + + settings := [s | + s := doc.resource.google_access_approval_project_settings[_] + contains(s.project_id, name) + ] + + count(settings) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_project.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'google_project.%s' should have 'google_access_approval_project_settings' associated", [name]), + "keyActualValue": sprintf("'google_project.%s' does not have Access Approval configured", [name]), + } +} + +# CASO 2: Access Approval configurado pero sin servicios inscritos. +CxPolicy[result] { + doc := input.document[i] + settings := doc.resource.google_access_approval_project_settings[name] + + not settings.enrolled_services + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_access_approval_project_settings.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "Must have at least one 'enrolled_services' block defined", + "keyActualValue": "'enrolled_services' is missing", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/negative1.tf b/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/negative1.tf new file mode 100644 index 00000000000..d4f71adbe76 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/negative1.tf @@ -0,0 +1,13 @@ +resource "google_project" "safe_project" { + name = "Safe Project" + project_id = "safe-123" + org_id = "12345" +} + +resource "google_access_approval_project_settings" "safe_settings" { + project_id = google_project.safe_project.project_id + + enrolled_services { + cloud_product = "all" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive1.tf b/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive1.tf new file mode 100644 index 00000000000..f7c28f9789d --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive1.tf @@ -0,0 +1,5 @@ +resource "google_project" "vulnerable_project" { + name = "Project Without Approval" + project_id = "vulnerable-123" + org_id = "12345" +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive2.tf b/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive2.tf new file mode 100644 index 00000000000..6e9ddf40f21 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive2.tf @@ -0,0 +1,4 @@ +resource "google_access_approval_project_settings" "empty_settings" { + project_id = "some-project-id" + # FALLO: No tiene enrolled_services +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..6099b814b74 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "GCP Access Approval Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "GCP Access Approval Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/README.md b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/README.md new file mode 100644 index 00000000000..c7b4f8dee59 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/README.md @@ -0,0 +1,57 @@ +# Regla KICS: Google API Key API Targets Missing + +## Descripción General + +Esta regla de severidad **MEDIA** audita la configuración de las **Google API Keys** (`google_apikeys_key`) para asegurar que el acceso esté limitado exclusivamente a los servicios necesarios. + +Cuando se genera una API Key en Google Cloud, por defecto tiene capacidad para invocar **cualquier API habilitada** en el proyecto. Esto representa un riesgo significativo de seguridad y costos; si una clave se ve comprometida (por ejemplo, al ser expuesta accidentalmente en el código fuente de una aplicación móvil o web), un atacante podría utilizarla para consumir servicios sensibles o de alto coste (como la API de Google Maps o modelos de IA) que no forman parte del propósito original de la aplicación. + +La mejor práctica de seguridad consiste en aplicar restricciones de "API Targets" para que la clave solo funcione con los servicios específicos para los que fue creada. + +## Lógica de la Regla + +La política evalúa dos escenarios de fallo en el código Terraform: +1. **Ausencia de Restricciones:** El recurso no define ningún bloque `restrictions`, dejando la clave totalmente desprotegida. +2. **Falta de Alcance de API:** El recurso define restricciones (como IPs o referrers), pero omite el bloque `api_targets`, permitiendo que esos orígenes autorizados consuman cualquier API del proyecto. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Restricciones Ausentes +* **Descripción:** La clave de API se define sin ningún tipo de control perimetral o de servicio. +* **Ubicación de la Alerta:** Bloque del recurso `google_apikeys_key`. + +### Caso 2: API Targets no Definidos +* **Descripción:** Se aplican restricciones de cliente, pero se mantiene el acceso ilimitado a todos los servicios de Google habilitados en el proyecto. +* **Ubicación de la Alerta:** Atributo `restrictions`. + +## Recurso Involucrado + +* `google_apikeys_key` + +## Solución + +Añada el bloque `api_targets` dentro de la sección `restrictions` especificando los servicios necesarios. + +```terraform +resource "google_apikeys_key" "secure_key" { + name = "production-maps-key" + + restrictions { + # Restricción de origen (ejemplo para navegador) + browser_key_restrictions { + allowed_referrers = ["[https://app.tu-empresa.com/](https://app.tu-empresa.com/)*"] + } + + # Restricción de servicios (Solución) + api_targets { + service = "maps-backend.googleapis.com" + } + api_targets { + service = "places-backend.googleapis.com" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json new file mode 100644 index 00000000000..e4a80048519 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "8097afd6-ef1a-4a58-b5f8-5d1b70ab4818", + "queryName": "Google API Key API Targets Missing", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that Google Cloud API Keys are restricted to specific APIs. By default, an API key can be used to access any API enabled in the project, which increases the blast radius if the key is compromised.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/apikeys_key#api_targets", + "platform": "Terraform", + "descriptionID": "8097afd6", + "cloudProvider": "gcp", + "cwe": "CWE-284", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego new file mode 100644 index 00000000000..ad76b2d3db5 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego @@ -0,0 +1,34 @@ +package Cx + +# CASO 1: No existe el bloque 'restrictions'. +CxPolicy[result] { + doc := input.document[i] + key := doc.resource.google_apikeys_key[name] + + not key.restrictions + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_apikeys_key.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'google_apikeys_key.%s' should have 'restrictions.api_targets' defined", [name]), + "keyActualValue": sprintf("'google_apikeys_key.%s' is missing the 'restrictions' block", [name]), + } +} + +# CASO 2: Existe 'restrictions', pero falta 'api_targets'. +CxPolicy[result] { + doc := input.document[i] + key := doc.resource.google_apikeys_key[name] + + key.restrictions + not key.restrictions.api_targets + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_apikeys_key.%s.restrictions", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "restrictions.api_targets should be defined", + "keyActualValue": "restrictions.api_targets is missing", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/negative1.tf b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/negative1.tf new file mode 100644 index 00000000000..46aac8df6af --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/negative1.tf @@ -0,0 +1,15 @@ +resource "google_apikeys_key" "key_fully_secure" { + name = "fully-secure-key" + display_name = "Compliant Key" + + restrictions { + browser_key_restrictions { + allowed_referrers = ["https://example.com/*"] + } + + # CORRECTO: Acceso limitado a servicios específicos + api_targets { + service = "translate.googleapis.com" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive1.tf b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive1.tf new file mode 100644 index 00000000000..27bb02ac13f --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive1.tf @@ -0,0 +1,5 @@ +resource "google_apikeys_key" "key_no_restrictions" { + name = "unrestricted-key" + display_name = "Unrestricted Key" + project = "my-project" +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive2.tf b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive2.tf new file mode 100644 index 00000000000..23ab9600179 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive2.tf @@ -0,0 +1,11 @@ +resource "google_apikeys_key" "key_no_targets" { + name = "partial-restricted-key" + display_name = "Key without API targets" + + restrictions { + server_key_restrictions { + allowed_ips = ["1.2.3.4"] + } + # FALLO: Falta el bloque api_targets + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..7afa3f11d84 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Google API Key API Targets Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Google API Key API Targets Missing", + "severity": "MEDIUM", + "line": 5, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/README.md b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/README.md new file mode 100644 index 00000000000..348522b5c62 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/README.md @@ -0,0 +1,54 @@ +# Regla KICS: Google API Key Restrictions (Manual) + +## Descripción General + +Esta regla informativa (INFO) audita la seguridad perimetral de las **Google API Keys** (`google_apikeys_key`). + +A diferencia de las identidades de IAM, las API Keys no se autentican mediante un usuario, sino que se validan por su simple posesión. Por ello, es imperativo restringir su uso a direcciones IP, dominios web o aplicaciones móviles específicas. + +Esta regla garantiza que se aplique el principio de defensa en profundidad. Dado que una herramienta de análisis estático no puede determinar si una dirección IP o un dominio configurado es legítimo o excesivamente permisivo, la regla alerta tanto ante la ausencia de restricciones como ante su presencia, forzando una revisión manual de la lista de permitidos. + +## Lógica de la Regla + +La política evalúa el recurso en dos etapas: +1. **Validación de Presencia:** Si falta el bloque `restrictions`, la clave se marca como vulnerable (acceso público). +2. **Validación Manual:** Si el bloque `restrictions` existe, se genera una alerta informativa para que el auditor confirme que los valores (IPs, referrers, etc.) coinciden con los activos corporativos autorizados. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Sin Restricciones (Vulnerable) +* **Descripción:** La clave de API carece de restricciones de cliente, permitiendo que cualquier persona con la clave pueda realizar llamadas desde cualquier lugar de Internet. +* **Ubicación de la Alerta:** Bloque del recurso `google_apikeys_key`. + +### Caso 2: Revisión de Restricciones (Manual Check) +* **Descripción:** La clave tiene restricciones configuradas. El auditor debe verificar que los valores definidos no sean genéricos o incorrectos. +* **Ubicación de la Alerta:** Atributo `restrictions`. + +## Recurso Involucrado + +* `google_apikeys_key` + +## Solución + +Implemente siempre el bloque `restrictions` utilizando el tipo de restricción que mejor se adapte al uso de la clave (Browser, Server, Android o iOS). + +```terraform +resource "google_apikeys_key" "secure_api_key" { + name = "frontend-maps-key" + + restrictions { + # Ejemplo: Clave restringida a un dominio específico + browser_key_restrictions { + allowed_referrers = ["[https://app.example.com/](https://app.example.com/)*"] + } + + # Recomendado: Combinar con restricción de API (API Targets) + api_targets { + service = "maps-backend.googleapis.com" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json new file mode 100644 index 00000000000..a91205ab304 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "7b3ba800-c190-4b65-ae4d-fa1e5f7bc75e", + "queryName": "Google API Key Restrictions (Manual)", + "severity": "INFO", + "category": "Access Control", + "descriptionText": "Ensures that Google Cloud API Keys are restricted. If restrictions are present, they must be manually verified to ensure they list the correct IPs, websites, or apps.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/apikeys_key", + "platform": "Terraform", + "descriptionID": "7b3ba800", + "cloudProvider": "gcp", + "cwe": "CWE-284", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego new file mode 100644 index 00000000000..c3edd6d961b --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego @@ -0,0 +1,33 @@ +package Cx + +# CASO 1: No hay restricciones definidas. +CxPolicy[result] { + doc := input.document[i] + key := doc.resource.google_apikeys_key[name] + + not key.restrictions + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_apikeys_key.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'google_apikeys_key.%s' should have a 'restrictions' block defined", [name]), + "keyActualValue": sprintf("'google_apikeys_key.%s' is missing the 'restrictions' block", [name]), + } +} + +# CASO 2: Hay restricciones definidas. +CxPolicy[result] { + doc := input.document[i] + key := doc.resource.google_apikeys_key[name] + + key.restrictions + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_apikeys_key.%s.restrictions", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Restrictions should be verified against allowed IPs/Referrers", + "keyActualValue": "Restrictions are present. Manual verification required.", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/negative1.tf b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/negative1.tf new file mode 100644 index 00000000000..c37bffc22a1 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/negative1.tf @@ -0,0 +1,4 @@ +# Caso negativo: No existen recursos de API Key, por lo que no hay riesgo que auditar. +resource "google_compute_network" "vpc" { + name = "secure-network" +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive1.tf b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive1.tf new file mode 100644 index 00000000000..6a744bca5ef --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive1.tf @@ -0,0 +1,6 @@ +resource "google_apikeys_key" "key_public" { + name = "public-key" + display_name = "Public Key" + project = "my-project" + # FALLO: No tiene bloque restrictions +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive2.tf b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive2.tf new file mode 100644 index 00000000000..d39236a798c --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive2.tf @@ -0,0 +1,11 @@ +resource "google_apikeys_key" "key_with_restrictions" { + name = "restricted-key" + display_name = "Restricted Key" + + restrictions { + # INFO: Esta sección requiere verificación manual de los valores + server_key_restrictions { + allowed_ips = ["192.168.1.1"] + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..a6e13f9849c --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Google API Key Restrictions (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Google API Key Restrictions (Manual)", + "severity": "INFO", + "line": 5, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/README.md b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/README.md new file mode 100644 index 00000000000..827f151e803 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/README.md @@ -0,0 +1,57 @@ +# Regla KICS: App Engine HTTPS Enforcement (Manual) + +## Descripción General + +Esta regla de auditoría verifica que las aplicaciones desplegadas en **Google App Engine** (Standard Environment) fuercen el uso exclusivo de conexiones cifradas mediante **HTTPS**. + +Servir contenido a través de HTTP sin cifrar expone los datos confidenciales de los usuarios y las credenciales de sesión a intercepciones. Para mitigar este riesgo, App Engine permite configurar una redirección automática de HTTP a HTTPS. + +Dado que App Engine suele utilizar un archivo de configuración externo (`app.yaml`) para definir el comportamiento de red, esta regla actúa como un control de gobierno que alerta si la política no está explícitamente definida en la infraestructura como código (Terraform) o si requiere una inspección manual de los artefactos de despliegue. + +## Lógica de la Regla + +La política evalúa el recurso `google_app_engine_standard_app_version` bajo dos escenarios: +1. **Configuración en Terraform:** Si el bloque `handlers` está presente, se asegura de que el atributo `security_level` esté configurado como `SECURE_ALWAYS`. Cualquier otro valor (como `SECURE_OPTIONAL`) disparará una alerta. +2. **Configuración Externa:** Si no se definen `handlers` en Terraform, la regla genera una alerta informativa (**INFO**) indicando que el cumplimiento depende de la configuración dentro del archivo `app.yaml` de la aplicación. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Nivel de Seguridad Inadecuado en Terraform +* **Descripción:** Los manejadores de URL permiten tráfico HTTP o no fuerzan la redirección segura. +* **Ubicación de la Alerta:** Atributo `handlers` dentro del recurso App Engine. + +### Caso 2: Verificación Manual de Archivos de Configuración +* **Descripción:** Terraform no gestiona la lógica de rutas. Se requiere validar el código fuente. +* **Acción Requerida:** Confirmar que en `app.yaml` todos los handlers críticos contengan: + ```yaml + secure: always + ``` +* **Ubicación de la Alerta:** Nivel de recurso `google_app_engine_standard_app_version`. + +## Recurso Involucrado + +* `google_app_engine_standard_app_version` + +## Solución + +Para forzar HTTPS desde Terraform, configure el `security_level` en cada handler: + +```terraform +resource "google_app_engine_standard_app_version" "secure_app" { + service = "api-service" + version_id = "v2" + runtime = "nodejs18" + + handlers { + url_regex = "/.*" + script { + script_path = "auto" + } + # Solución técnica + security_level = "SECURE_ALWAYS" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json new file mode 100644 index 00000000000..38b32c311e5 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "52b7bc15-032e-4dd7-b9c3-6dc9698aa131", + "queryName": "App Engine HTTPS Enforcement (Manual)", + "severity": "INFO", + "category": "Encryption", + "descriptionText": "Ensures that Google App Engine applications enforce HTTPS connections. This is typically configured in 'app.yaml' using 'secure: always' or in Terraform via the 'handlers' block with 'security_level'. Manual verification is often required.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/app_engine_standard_app_version#security_level", + "platform": "Terraform", + "descriptionID": "52b7bc15", + "cloudProvider": "gcp", + "cwe": "CWE-319", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego new file mode 100644 index 00000000000..13dd18563ce --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego @@ -0,0 +1,42 @@ +package Cx + +ensure_array(x) = x { is_array(x) } +ensure_array(x) = [x] { not is_array(x) } + +# CASO 1: Configuración Insegura en los handlers definidos. +CxPolicy[result] { + doc := input.document[i] + app := doc.resource.google_app_engine_standard_app_version[name] + + app.handlers + + handlers_list := ensure_array(app.handlers) + handler := handlers_list[_] + + sec_level := object.get(handler, "security_level", "UNSPECIFIED") + sec_level != "SECURE_ALWAYS" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_app_engine_standard_app_version.%s.handlers", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'handlers.security_level' should be set to 'SECURE_ALWAYS'", + "keyActualValue": sprintf("'handlers.security_level' is set to '%s'", [sec_level]), + } +} + +# CASO 2: Configuración Ausente en Terraform (Requiere revisión de app.yaml). +CxPolicy[result] { + doc := input.document[i] + app := doc.resource.google_app_engine_standard_app_version[name] + + not app.handlers + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_app_engine_standard_app_version.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "If handlers are not defined in Terraform, verify 'app.yaml' contains 'secure: always'", + "keyActualValue": "Terraform does not define handlers. Manual verification of 'app.yaml' required.", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/negative1.tf b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/negative1.tf new file mode 100644 index 00000000000..c677e558ac9 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/negative1.tf @@ -0,0 +1,10 @@ +resource "google_app_engine_standard_app_version" "app_secure" { + service = "frontend" + version_id = "v1" + runtime = "php81" + + handlers { + url_regex = "/.*" + security_level = "SECURE_ALWAYS" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive1.tf b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive1.tf new file mode 100644 index 00000000000..9e6e7822418 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive1.tf @@ -0,0 +1,11 @@ +resource "google_app_engine_standard_app_version" "app_insecure" { + service = "default" + version_id = "v1" + runtime = "python39" + + handlers { + url_regex = "/.*" + # FALLO: security_level no es SECURE_ALWAYS + security_level = "SECURE_OPTIONAL" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive2.tf b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive2.tf new file mode 100644 index 00000000000..7ef1af37bdb --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive2.tf @@ -0,0 +1,6 @@ +resource "google_app_engine_standard_app_version" "app_no_handlers" { + service = "backend" + version_id = "v1" + runtime = "go119" + # FALLO: Falta el bloque handlers, requiere revisión de app.yaml +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..d4dae947860 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "App Engine HTTPS Enforcement (Manual)", + "severity": "INFO", + "line": 6, + "fileName": "positive1.tf" + }, + { + "queryName": "App Engine HTTPS Enforcement (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/README.md b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/README.md new file mode 100644 index 00000000000..133689f6385 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/README.md @@ -0,0 +1,49 @@ +# Regla KICS: GCP Compute Logging Service Disabled + +## Descripción General + +Esta regla de **Observabilidad** verifica que las instancias de **Google Compute Engine** (`google_compute_instance`) tengan habilitado el envío de registros al servicio de **Cloud Logging** mediante el metadato `google-logging-enabled`. + +La visibilidad es un componente crítico de la seguridad. El agente de Google Cloud (Ops Agent) utiliza este flag para determinar si debe transmitir logs del sistema operativo y de aplicaciones a la consola centralizada de Google Cloud. Sin estos registros, la detección de intrusiones, el análisis forense y la resolución de errores operativos se vuelven tareas inviables. + +## Lógica de la Regla + +La política audita el recurso evaluando tres estados posibles de fallo para maximizar la precisión del reporte: +1. **Bloque Ausente:** Si falta todo el bloque `metadata`. +2. **Clave Ausente:** Si el bloque `metadata` existe pero no define la clave requerida. +3. **Valor Incorrecto:** Si la clave existe pero se ha establecido explícitamente como `"false"`. + +## Casos de Fallo Detectados + +--- + +### Caso 1: Configuración de Metadatos Ausente +* **Descripción:** La instancia no define ningún metadato, omitiendo por tanto el servicio de logging. +* **Ubicación de la Alerta:** Nivel de recurso `google_compute_instance`. + +### Caso 2: Flag de Logging Faltante +* **Descripción:** Se usan metadatos pero se omite específicamente `google-logging-enabled`. +* **Ubicación de la Alerta:** Atributo `metadata`. + +### Caso 3: Logging Deshabilitado +* **Descripción:** Se ha configurado el valor `"false"`, bloqueando activamente la ingesta de logs. +* **Ubicación de la Alerta:** Atributo `google-logging-enabled`. + +## Recurso Involucrado + +* `google_compute_instance` + +## Solución + +Asegúrese de establecer el metadato en `"true"` para habilitar el servicio. + +```terraform +resource "google_compute_instance" "secure_vm" { + name = "prod-server" + machine_type = "e2-medium" + zone = "us-central1-a" + + metadata = { + "google-logging-enabled" = "true" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json new file mode 100644 index 00000000000..c2038150816 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "ccefc589-0310-45a4-a2b6-d558e629e019", + "queryName": "GCP Compute Logging Service Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that the 'google-logging-enabled' metadata flag is set to 'true' for Google Compute Engine instances. This flag configures the instance to send logs to Cloud Logging.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#metadata", + "platform": "Terraform", + "descriptionID": "ccefc589", + "cloudProvider": "gcp", + "cwe": "CWE-778", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego new file mode 100644 index 00000000000..c0f0b0534a6 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego @@ -0,0 +1,51 @@ +package Cx + +# REGLA 1: El bloque 'metadata' no existe. +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.google_compute_instance[name] + + not instance.metadata + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_compute_instance.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'metadata' block should be defined and contain 'google-logging-enabled'", + "keyActualValue": "'metadata' block is missing", + } +} + +# REGLA 2: El bloque 'metadata' existe pero le falta la clave 'google-logging-enabled'. +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.google_compute_instance[name] + + instance.metadata + not instance.metadata["google-logging-enabled"] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_compute_instance.%s.metadata", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'google-logging-enabled' should be defined within metadata", + "keyActualValue": "'google-logging-enabled' is missing in metadata", + } +} + +# REGLA 3: La clave existe pero su valor es 'false'. +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.google_compute_instance[name] + + val := instance.metadata["google-logging-enabled"] + val == "false" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_compute_instance.%s.metadata.google-logging-enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'google-logging-enabled' should be set to 'true'", + "keyActualValue": "'google-logging-enabled' is set to 'false'", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/negative1.tf b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/negative1.tf new file mode 100644 index 00000000000..c93e52f1de6 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/negative1.tf @@ -0,0 +1,6 @@ +resource "google_compute_instance" "vm_ok" { + name = "instance-compliant" + metadata = { + "google-logging-enabled" = "true" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive1.tf b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive1.tf new file mode 100644 index 00000000000..50d669dfeca --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive1.tf @@ -0,0 +1,4 @@ +resource "google_compute_instance" "vm_fail_1" { + name = "instance-no-metadata" + machine_type = "e2-medium" +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive2.tf b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive2.tf new file mode 100644 index 00000000000..0ec28c90e91 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive2.tf @@ -0,0 +1,6 @@ +resource "google_compute_instance" "vm_fail_2" { + name = "instance-no-flag" + metadata = { + foo = "bar" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive3.tf b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive3.tf new file mode 100644 index 00000000000..d2d93df0e9c --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive3.tf @@ -0,0 +1,6 @@ +resource "google_compute_instance" "vm_fail_3" { + name = "instance-disabled" + metadata = { + "google-logging-enabled" = "false" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..a8f97e871bb --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "GCP Compute Logging Service Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "GCP Compute Logging Service Disabled", + "severity": "MEDIUM", + "line": 3, + "fileName": "positive2.tf" + }, + { + "queryName": "GCP Compute Logging Service Disabled", + "severity": "MEDIUM", + "line": 4, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/README.md b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/README.md new file mode 100644 index 00000000000..7e218cf2b69 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/README.md @@ -0,0 +1,51 @@ +# Regla KICS: GKE Default Service Account Used + +## Descripción General + +Esta regla de severidad **ALTA** verifica que los clústeres y pools de nodos de **Google Kubernetes Engine (GKE)** no utilicen la cuenta de servicio predeterminada de Compute Engine. + +Por defecto, si no se especifica el atributo `service_account`, GKE utiliza la cuenta de servicio predeterminada del proyecto (`PROJECT_NUMBER-compute@developer.gserviceaccount.com`). Esta cuenta posee automáticamente el rol de **Editor**, lo que otorga a los nodos (y potencialmente a los Pods) permisos extensos para modificar recursos en GCP, como buckets de almacenamiento, redes VPC y otras instancias. Utilizar una cuenta de servicio dedicada con privilegios mínimos reduce drásticamente el "blast radius" en caso de un compromiso de seguridad en el clúster. + +## Lógica de la Regla + +La política audita los recursos `google_container_cluster` y `google_container_node_pool` bajo los siguientes criterios: +1. **Falta de Atributo:** Identifica si el bloque `node_config` carece de la clave `service_account`. +2. **Identificación de Riesgo:** La alerta se dispara al detectar que el clúster delegará su identidad a la cuenta de servicio más privilegiada del proyecto por defecto. + +## Casos de Fallo Detectados + +--- + +### Caso 1: Uso Implícito en el Clúster +* **Descripción:** Se define un clúster de GKE sin especificar una identidad para los nodos. +* **Ubicación de la Alerta:** Atributo `node_config` del recurso `google_container_cluster`. + +### Caso 2: Uso Implícito en el Node Pool +* **Descripción:** Se crea un pool de nodos adicional que hereda la cuenta de servicio por defecto. +* **Ubicación de la Alerta:** Atributo `node_config` del recurso `google_container_node_pool`. + +## Recurso Involucrado + +* `google_container_cluster` +* `google_container_node_pool` + +## Solución + +Cree una Service Account personalizada con los permisos mínimos necesarios (ej. roles de logging, monitoring y acceso a registry) y asígnela explícitamente. + +```terraform +resource "google_service_account" "gke_nodes_sa" { + account_id = "gke-nodes-identity" + display_name = "GKE Nodes Minimal Service Account" +} + +resource "google_container_cluster" "secure_cluster" { + name = "production-cluster" + location = "us-central1" + + node_config { + # Solución: Identidad dedicada + service_account = google_service_account.gke_nodes_sa.email + oauth_scopes = ["[https://www.googleapis.com/auth/cloud-platform](https://www.googleapis.com/auth/cloud-platform)"] + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json new file mode 100644 index 00000000000..6fd64f265d2 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "8ef3f681-6ef1-4bbd-94bb-f9fe6d0626da", + "queryName": "GKE Default Service Account Used", + "severity": "HIGH", + "category": "Access Control", + "descriptionText": "Ensures that GKE clusters do not use the default Compute Engine Service Account. The default account has the 'Editor' role, granting nodes excessive write permissions to the project.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_cluster#service_account", + "platform": "Terraform", + "descriptionID": "8ef3f681", + "cloudProvider": "gcp", + "cwe": "CWE-276", + "riskScore": 9.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego new file mode 100644 index 00000000000..ecb14c5bfcc --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego @@ -0,0 +1,33 @@ +package Cx + +# REGLA 1: Service Account ausente en google_container_cluster. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_cluster[name] + + not resource.node_config.service_account + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s.node_config", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'service_account' should be explicitly defined in node_config", + "keyActualValue": "'service_account' is missing, defaulting to the Compute Engine default service account", + } +} + +# REGLA 2: Service Account ausente en google_container_node_pool. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_node_pool[name] + + not resource.node_config.service_account + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_node_pool.%s.node_config", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'service_account' should be explicitly defined in node_config", + "keyActualValue": "'service_account' is missing, defaulting to the Compute Engine default service account", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/negative1.tf b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/negative1.tf new file mode 100644 index 00000000000..7454d8cb1c4 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/negative1.tf @@ -0,0 +1,6 @@ +resource "google_container_cluster" "pass_cluster" { + name = "secure-cluster" + node_config { + service_account = "dedicated-sa@project.iam.gserviceaccount.com" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive1.tf new file mode 100644 index 00000000000..ee0134114dc --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive1.tf @@ -0,0 +1,9 @@ +resource "google_container_cluster" "fail_cluster" { + name = "insecure-cluster" + location = "us-central1" + + node_config { + machine_type = "e2-medium" + # FALLO: Falta service_account + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive2.tf new file mode 100644 index 00000000000..f7a9977968e --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive2.tf @@ -0,0 +1,9 @@ +resource "google_container_node_pool" "fail_pool" { + name = "insecure-pool" + cluster = "some-cluster" + + node_config { + # FALLO: Falta service_account + preemptible = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive_expected_result.json new file mode 100644 index 00000000000..1fc03b54785 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "GKE Default Service Account Used", + "severity": "HIGH", + "line": 5, + "fileName": "positive1.tf" + }, + { + "queryName": "GKE Default Service Account Used", + "severity": "HIGH", + "line": 5, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/README.md b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/README.md new file mode 100644 index 00000000000..8cc831522a7 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/README.md @@ -0,0 +1,46 @@ +# Regla KICS: GKE Image Vulnerability Scanning Disabled + +## Descripción General + +Esta regla de severidad **ALTA** verifica que el escaneo automático de vulnerabilidades esté habilitado en los clústeres de **Google Kubernetes Engine (GKE)** a través del Security Posture Dashboard. + +Habilitar el escaneo de vulnerabilidades permite a GKE inspeccionar continuamente las imágenes de contenedor que se ejecutan en las cargas de trabajo del clúster. GKE compara los paquetes del sistema operativo del contenedor con bases de datos públicas de vulnerabilidades (CVEs). Sin esta función activa, la organización carece de visibilidad sobre si las aplicaciones desplegadas contienen fallos de seguridad conocidos que podrían ser explotados por atacantes. + +## Lógica de la Regla + +La política audita el recurso `google_container_cluster` evaluando tres estados de riesgo: +1. **Omisión de Configuración:** El clúster no tiene definido el bloque `security_posture_config`. +2. **Modo No Especificado:** El bloque existe pero no define el parámetro `vulnerability_mode`. +3. **Deshabilitación Explícita:** El parámetro `vulnerability_mode` está configurado como `VULNERABILITY_DISABLED`. + +## Casos de Fallo Detectados + +--- + +### Caso 1: Configuración de Postura de Seguridad Ausente +* **Descripción:** El clúster se aprovisiona con la configuración por defecto de Google, que no siempre incluye el escaneo avanzado activo. +* **Ubicación de la Alerta:** Nivel de recurso `google_container_cluster`. + +### Caso 2: Vulnerability Mode Faltante o Deshabilitado +* **Descripción:** Se define la configuración de seguridad pero se omite o se desactiva explícitamente el escaneo de imágenes. +* **Ubicación de la Alerta:** Atributo `vulnerability_mode` dentro de `security_posture_config`. + +## Recurso Involucrado + +* `google_container_cluster` + +## Solución + +Habilite el escaneo configurando el bloque `security_posture_config` con un modo de vulnerabilidad válido. + +```terraform +resource "google_container_cluster" "compliant_cluster" { + name = "secure-production-cluster" + location = "us-central1" + + # Solución recomendada + security_posture_config { + mode = "BASIC" + vulnerability_mode = "VULNERABILITY_BASIC" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json new file mode 100644 index 00000000000..129e38d16fe --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "30b5b4bb-a4dd-41b5-9caf-32e9b017a35e", + "queryName": "GKE Image Vulnerability Scanning Disabled", + "severity": "HIGH", + "category": "Supply-Chain", + "descriptionText": "Ensures that Image Vulnerability Scanning is enabled in GKE clusters via the security posture configuration. This feature automatically scans workloads for known vulnerabilities.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_cluster#vulnerability_mode", + "platform": "Terraform", + "descriptionID": "30b5b4bb", + "cloudProvider": "gcp", + "cwe": "CWE-1395", + "riskScore": 9.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego new file mode 100644 index 00000000000..d3736459d35 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego @@ -0,0 +1,51 @@ +package Cx + +# REGLA 1: Bloque 'security_posture_config' ausente. +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + not cluster.security_posture_config + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'security_posture_config' block should be defined", + "keyActualValue": "'security_posture_config' block is missing", + } +} + +# REGLA 2: Atributo 'vulnerability_mode' ausente dentro del bloque. +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + cluster.security_posture_config + not cluster.security_posture_config.vulnerability_mode + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s.security_posture_config", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'vulnerability_mode' should be defined within security_posture_config", + "keyActualValue": "'vulnerability_mode' is missing", + } +} + +# REGLA 3: Atributo 'vulnerability_mode' configurado como 'VULNERABILITY_DISABLED'. +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + mode := cluster.security_posture_config.vulnerability_mode + mode == "VULNERABILITY_DISABLED" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s.security_posture_config.vulnerability_mode", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'vulnerability_mode' should be 'VULNERABILITY_BASIC' or 'VULNERABILITY_ENTERPRISE'", + "keyActualValue": "'vulnerability_mode' is set to 'VULNERABILITY_DISABLED'", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative1.tf b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative1.tf new file mode 100644 index 00000000000..59cb11a0bb0 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative1.tf @@ -0,0 +1,8 @@ +resource "google_container_cluster" "pass_vulnerability_basic" { + name = "compliant-cluster-basic" + + security_posture_config { + mode = "BASIC" + vulnerability_mode = "VULNERABILITY_BASIC" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative2.tf b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative2.tf new file mode 100644 index 00000000000..ed4e5fdb59b --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative2.tf @@ -0,0 +1,8 @@ +resource "google_container_cluster" "pass_vulnerability_enterprise" { + name = "compliant-cluster-enterprise" + + security_posture_config { + mode = "ENTERPRISE" + vulnerability_mode = "VULNERABILITY_ENTERPRISE" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive1.tf new file mode 100644 index 00000000000..47c80cdd8b0 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive1.tf @@ -0,0 +1,5 @@ +resource "google_container_cluster" "fail_block_missing" { + name = "no-security-config" + location = "us-central1" + # Fallo: No existe el bloque de postura de seguridad +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive2.tf new file mode 100644 index 00000000000..fff3f5bf020 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive2.tf @@ -0,0 +1,8 @@ +resource "google_container_cluster" "fail_attr_missing" { + name = "partial-security-config" + + security_posture_config { + mode = "BASIC" + # Fallo: Falta definir vulnerability_mode dentro del bloque + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive3.tf b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive3.tf new file mode 100644 index 00000000000..cf0bab1c4d3 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive3.tf @@ -0,0 +1,8 @@ +resource "google_container_cluster" "fail_mode_disabled" { + name = "disabled-scanning-cluster" + + security_posture_config { + mode = "BASIC" + vulnerability_mode = "VULNERABILITY_DISABLED" # Fallo: Deshabilitado + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..96bf72e2d4e --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "GKE Image Vulnerability Scanning Disabled", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "GKE Image Vulnerability Scanning Disabled", + "severity": "HIGH", + "line": 4, + "fileName": "positive2.tf" + }, + { + "queryName": "GKE Image Vulnerability Scanning Disabled", + "severity": "HIGH", + "line": 6, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/README.md b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/README.md new file mode 100644 index 00000000000..79981201ecc --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/README.md @@ -0,0 +1,38 @@ +# Regla KICS: GKE Service Account IAM Review (Manual) + +## Descripción General + +Esta regla informativa (INFO) de **Supply Chain** audita las identidades utilizadas por los nodos de **Google Kubernetes Engine (GKE)** cuando se han configurado cuentas de servicio personalizadas. + +El uso de cuentas de servicio personalizadas es el primer paso hacia el principio de menor privilegio. Sin embargo, si a esta cuenta se le asignan roles con permisos de escritura (como `roles/artifactregistry.writer` o `roles/storage.objectAdmin`), un atacante que comprometa un nodo podría modificar o reemplazar las imágenes de contenedor en el registro. Esto permitiría ataques de persistencia o escalada de privilegios en otros clústeres que consuman esas mismas imágenes. + +## Lógica de la Regla + +La política identifica los recursos `google_container_cluster` y `google_container_node_pool` que definen explícitamente una `service_account`. Al ser una verificación manual, genera una alerta informativa sobre la línea de la cuenta de servicio para que el auditor valide en el proyecto de GCP que los roles asociados son exclusivamente de **Lectura**. + +## Casos de Fallo Detectados + +--- + +### Caso 1: Revisión de SA en Clúster +* **Descripción:** Se ha definido una identidad personalizada para el clúster. Se debe verificar que no tenga permisos de "Push" al registro de imágenes. +* **Ubicación de la Alerta:** Atributo `service_account` en `google_container_cluster`. + +### Caso 2: Revisión de SA en Node Pool +* **Descripción:** Un pool de nodos específico utiliza una identidad propia que requiere auditoría de roles IAM. +* **Ubicación de la Alerta:** Atributo `service_account` en `google_container_node_pool`. + +## Recurso Involucrado + +* `google_container_cluster` +* `google_container_node_pool` + +## Solución + +Asegúrese de que la Service Account asignada solo posea roles de lectura para el registro de imágenes utilizado. + +**Roles Recomendados:** +* `roles/artifactregistry.reader` (para Artifact Registry) +* `roles/storage.objectViewer` (para Container Registry/GCR) +* `roles/logging.logWriter` +* `roles/monitoring.metricWriter` \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json new file mode 100644 index 00000000000..5ace58c4a29 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "b29ff836-5b2e-4089-a40c-086426ef3980", + "queryName": "GKE Service Account IAM Review (Manual)", + "severity": "INFO", + "category": "Supply-Chain", + "descriptionText": "A custom Service Account is configured for GKE nodes. Manual verification is required to ensure this account has Read-Only access to Container Registries (e.g., 'roles/storage.objectViewer') and not Write access.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam_member", + "platform": "Terraform", + "descriptionID": "b29ff836", + "cloudProvider": "gcp", + "cwe": "CWE-276", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego new file mode 100644 index 00000000000..a3c5faa3751 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego @@ -0,0 +1,33 @@ +package Cx + +# REGLA 1: Detección de SA personalizada en google_container_cluster. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_cluster[name] + + sa := resource.node_config.service_account + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s.node_config.service_account", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Custom Service Account IAM roles should be verified as Read-Only", + "keyActualValue": sprintf("Custom Service Account '%s' found. Manual IAM verification required.", [sa]), + } +} + +# REGLA 2: Detección de SA personalizada en google_container_node_pool. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_node_pool[name] + + sa := resource.node_config.service_account + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_node_pool.%s.node_config.service_account", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Custom Service Account IAM roles should be verified as Read-Only", + "keyActualValue": sprintf("Custom Service Account '%s' found. Manual IAM verification required.", [sa]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/negative1.tf b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/negative1.tf new file mode 100644 index 00000000000..85a988a70c7 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/negative1.tf @@ -0,0 +1,5 @@ +# En este caso negativo, no hay SA personalizada (se encargaría la regla de SA por defecto) +resource "google_container_cluster" "no_custom_sa" { + name = "default-sa-cluster" + # No define node_config.service_account +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive1.tf new file mode 100644 index 00000000000..72e297282f2 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive1.tf @@ -0,0 +1,9 @@ +resource "google_container_cluster" "audit_cluster" { + name = "custom-sa-cluster" + location = "us-central1" + + node_config { + # INFO: Esta cuenta requiere revisión manual de IAM + service_account = "gke-nodes-custom@project.iam.gserviceaccount.com" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive2.tf new file mode 100644 index 00000000000..5a9cf868c63 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive2.tf @@ -0,0 +1,9 @@ +resource "google_container_node_pool" "audit_pool" { + name = "custom-sa-pool" + cluster = "my-cluster" + + node_config { + # INFO: Esta cuenta requiere revisión manual de IAM + service_account = "dedicated-pool-sa@project.iam.gserviceaccount.com" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive_expected_result.json new file mode 100644 index 00000000000..c62bc67dd8a --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "GKE Service Account IAM Review (Manual)", + "severity": "INFO", + "line": 7, + "fileName": "positive1.tf" + }, + { + "queryName": "GKE Service Account IAM Review (Manual)", + "severity": "INFO", + "line": 7, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/README.md b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/README.md new file mode 100644 index 00000000000..cf6928760c7 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/README.md @@ -0,0 +1,47 @@ +# Regla KICS: GKE Metadata Server Disabled + +## Descripción General + +Esta regla de severidad **ALTA** verifica que los nodos de GKE utilicen el **GKE Metadata Server** para gestionar las identidades de las cargas de trabajo. + +Por defecto, los nodos de GKE tienen acceso al servidor de metadatos de Compute Engine (GCE), el cual expone información sensible del host y tokens de acceso de la cuenta de servicio del nodo. Si un atacante logra comprometer un pod, podría consultar este endpoint para obtener credenciales y realizar un movimiento lateral hacia otros recursos del proyecto. Al habilitar `GKE_METADATA`, se activa el puente hacia **Workload Identity**, interceptando estas peticiones y limitando el acceso solo a lo que el Pod tiene permitido específicamente. + +## Lógica de la Regla + +La política audita los recursos `google_container_cluster` y `google_container_node_pool` bajo dos criterios: +1. **Omisión del Bloque:** Verifica si `workload_metadata_config` está presente dentro de `node_config`. +2. **Modo Inseguro:** Asegura que el atributo `mode` sea estrictamente `GKE_METADATA`. El valor `GCE_METADATA` (valor predeterminado heredado) se considera vulnerable. + +## Casos de Fallo Detectados + +--- + +### Caso 1: Configuración de Metadatos Ausente +* **Descripción:** El clúster o pool de nodos no define el modo de metadatos de carga de trabajo. +* **Ubicación de la Alerta:** Atributo `node_config`. + +### Caso 2: Uso de GCE_METADATA (Legacy/Vulnerable) +* **Descripción:** Se permite explícitamente el acceso de los pods a los metadatos de la instancia de cómputo subyacente. +* **Ubicación de la Alerta:** Atributo `mode` dentro de `workload_metadata_config`. + +## Recurso Involucrado + +* `google_container_cluster` +* `google_container_node_pool` + +## Solución + +Configure el bloque `workload_metadata_config` con el modo `GKE_METADATA`. + +```terraform +resource "google_container_node_pool" "compliant_pool" { + name = "secure-pool" + cluster = google_container_cluster.primary.name + + node_config { + # Solución técnica + workload_metadata_config { + mode = "GKE_METADATA" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json new file mode 100644 index 00000000000..e15967fcbb7 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "e858428b-7650-4a62-a7d4-5b0d4c9afdd6", + "queryName": "GKE Metadata Server Disabled", + "severity": "HIGH", + "category": "Access Control", + "descriptionText": "Ensures that the GKE Metadata Server is enabled by setting 'workload_metadata_config.mode' to 'GKE_METADATA'. This prevents pods from accessing the sensitive Compute Engine metadata server and node credentials.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_node_pool#mode", + "platform": "Terraform", + "descriptionID": "e858428b", + "cloudProvider": "gcp", + "cwe": "CWE-284", + "riskScore": 9.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego new file mode 100644 index 00000000000..d853b869a5c --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego @@ -0,0 +1,65 @@ +package Cx + +# REGLA 1: 'workload_metadata_config' ausente en google_container_cluster +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_cluster[name] + + not resource.node_config.workload_metadata_config + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s.node_config", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'workload_metadata_config' should be defined with mode 'GKE_METADATA'", + "keyActualValue": "'workload_metadata_config' is missing", + } +} + +# REGLA 2: 'workload_metadata_config' ausente en google_container_node_pool +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_node_pool[name] + + not resource.node_config.workload_metadata_config + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_node_pool.%s.node_config", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'workload_metadata_config' should be defined with mode 'GKE_METADATA'", + "keyActualValue": "'workload_metadata_config' is missing", + } +} + +# REGLA 3: Modo incorrecto en google_container_cluster +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_cluster[name] + + resource.node_config.workload_metadata_config.mode != "GKE_METADATA" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s.node_config.workload_metadata_config.mode", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'mode' should be set to 'GKE_METADATA'", + "keyActualValue": sprintf("'mode' is set to '%s'", [resource.node_config.workload_metadata_config.mode]), + } +} + +# REGLA 4: Modo incorrecto en google_container_node_pool +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_node_pool[name] + + resource.node_config.workload_metadata_config.mode != "GKE_METADATA" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_node_pool.%s.node_config.workload_metadata_config.mode", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'mode' should be set to 'GKE_METADATA'", + "keyActualValue": sprintf("'mode' is set to '%s'", [resource.node_config.workload_metadata_config.mode]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/negative1.tf b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/negative1.tf new file mode 100644 index 00000000000..d9326a50b15 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/negative1.tf @@ -0,0 +1,8 @@ +resource "google_container_cluster" "pass_cluster" { + name = "secure-cluster" + node_config { + workload_metadata_config { + mode = "GKE_METADATA" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/negative2.tf b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/negative2.tf new file mode 100644 index 00000000000..ca108391fbc --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/negative2.tf @@ -0,0 +1,9 @@ +resource "google_container_node_pool" "pass_pool" { + name = "secure-pool" + cluster = "my-cluster" + node_config { + workload_metadata_config { + mode = "GKE_METADATA" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive1.tf new file mode 100644 index 00000000000..28c1bac2b70 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive1.tf @@ -0,0 +1,9 @@ +resource "google_container_cluster" "fail_cluster_no_block" { + name = "cluster-missing-metadata-config" + location = "us-central1" + + node_config { + machine_type = "e2-medium" + # FALLO: No existe workload_metadata_config + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive2.tf new file mode 100644 index 00000000000..8fd70a39d23 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive2.tf @@ -0,0 +1,9 @@ +resource "google_container_node_pool" "fail_pool_no_block" { + name = "pool-missing-metadata-config" + cluster = "my-cluster" + + node_config { + preemptible = true + # FALLO: No existe workload_metadata_config + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive3.tf b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive3.tf new file mode 100644 index 00000000000..f267aff7350 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive3.tf @@ -0,0 +1,9 @@ +resource "google_container_cluster" "fail_cluster_wrong_mode" { + name = "cluster-gce-mode" + + node_config { + workload_metadata_config { + mode = "GCE_METADATA" # FALLO: Debe ser GKE_METADATA + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive4.tf b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive4.tf new file mode 100644 index 00000000000..ea2bc5ced9d --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive4.tf @@ -0,0 +1,10 @@ +resource "google_container_node_pool" "fail_pool_wrong_mode" { + name = "pool-gce-mode" + cluster = "my-cluster" + + node_config { + workload_metadata_config { + mode = "GCE_METADATA" # FALLO: Debe ser GKE_METADATA + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..defbff8b43b --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive_expected_result.json @@ -0,0 +1,26 @@ +[ + { + "queryName": "GKE Metadata Server Disabled", + "severity": "HIGH", + "line": 5, + "fileName": "positive1.tf" + }, + { + "queryName": "GKE Metadata Server Disabled", + "severity": "HIGH", + "line": 5, + "fileName": "positive2.tf" + }, + { + "queryName": "GKE Metadata Server Disabled", + "severity": "HIGH", + "line": 6, + "fileName": "positive3.tf" + }, + { + "queryName": "GKE Metadata Server Disabled", + "severity": "HIGH", + "line": 7, + "fileName": "positive4.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/README.md b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/README.md new file mode 100644 index 00000000000..0501cd7724e --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/README.md @@ -0,0 +1,52 @@ +# Regla KICS: GKE Sandbox (gVisor) Disabled + +## Descripción General + +Esta regla de severidad **BAJA** verifica si los pools de nodos de GKE tienen habilitado **GKE Sandbox (gVisor)** para un aislamiento reforzado. + +GKE Sandbox utiliza **gVisor**, un kernel de espacio de usuario que proporciona una barrera de seguridad adicional entre las aplicaciones y el kernel del host. Al interceptar y filtrar las llamadas al sistema, gVisor mitiga el riesgo de ataques de escape de contenedor, donde un proceso malicioso intenta comprometer el nodo subyacente. Aunque gVisor introduce un ligero overhead de rendimiento, es una **Configuración Insegura** omitirlo en entornos que ejecutan código no confiable o aplicaciones multi-tenant. + +## Lógica de la Regla + +La política audita los recursos `google_container_cluster` y `google_container_node_pool`: +1. **Omisión del Bloque:** Detecta si `sandbox_config` no está presente en el `node_config`. +2. **Tipo Incorrecto:** Verifica que el `sandbox_type` sea explícitamente `"gvisor"`. + +## Casos de Fallo Detectados + +--- + +### Caso 1: Sandbox no configurado en Clúster +* **Descripción:** Los nodos predeterminados del clúster no utilizan el aislamiento de gVisor. +* **Ubicación de la Alerta:** Atributo `node_config`. + +### Caso 2: Sandbox no configurado en Node Pool +* **Descripción:** Se ha creado un pool de nodos adicional que carece de protección de Sandbox. +* **Ubicación de la Alerta:** Atributo `node_config`. + +### Caso 3: Tipo de Sandbox Inseguro +* **Descripción:** Se define el bloque pero se utiliza un valor distinto a `gvisor`, lo que desactiva la protección buscada. +* **Ubicación de la Alerta:** Atributo `sandbox_type`. + +## Recurso Involucrado + +* `google_container_cluster` +* `google_container_node_pool` + +## Solución + +Habilite gVisor asegurándose de usar el tipo de imagen compatible `COS_CONTAINERD`. + +```terraform +resource "google_container_node_pool" "secure_pool" { + name = "untrusted-code-pool" + cluster = google_container_cluster.primary.name + + node_config { + image_type = "COS_CONTAINERD" + + sandbox_config { + sandbox_type = "gvisor" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json new file mode 100644 index 00000000000..327a2de5107 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "6c8a93a9-c0c5-4314-8ee6-3bcb3a0dbd70", + "queryName": "GKE Sandbox (gVisor) Disabled", + "severity": "LOW", + "category": "Insecure Configurations", + "descriptionText": "GKE Sandbox (gVisor) provides an extra layer of defense for untrusted workloads. It is not enabled on this Node Pool. Consider enabling it if this pool runs untrusted code (e.g., SaaS user scripts).", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_node_pool#sandbox_type", + "platform": "Terraform", + "descriptionID": "6c8a93a9", + "cloudProvider": "gcp", + "cwe": "CWE-1038", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego new file mode 100644 index 00000000000..7a81e5cd947 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego @@ -0,0 +1,65 @@ +package Cx + +# REGLA 1: Bloque 'sandbox_config' ausente en google_container_cluster. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_cluster[name] + + not resource.node_config.sandbox_config + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s.node_config", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'sandbox_config' should be defined with sandbox_type 'gvisor'", + "keyActualValue": "'sandbox_config' is missing", + } +} + +# REGLA 2: Bloque 'sandbox_config' ausente en google_container_node_pool. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_node_pool[name] + + not resource.node_config.sandbox_config + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_node_pool.%s.node_config", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'sandbox_config' should be defined with sandbox_type 'gvisor'", + "keyActualValue": "'sandbox_config' is missing", + } +} + +# REGLA 3: sandbox_type incorrecto en google_container_cluster. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_cluster[name] + + resource.node_config.sandbox_config.sandbox_type != "gvisor" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s.node_config.sandbox_config.sandbox_type", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'sandbox_type' should be 'gvisor'", + "keyActualValue": sprintf("'sandbox_type' is set to '%s'", [resource.node_config.sandbox_config.sandbox_type]), + } +} + +# REGLA 4: sandbox_type incorrecto en google_container_node_pool. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_node_pool[name] + + resource.node_config.sandbox_config.sandbox_type != "gvisor" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_node_pool.%s.node_config.sandbox_config.sandbox_type", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'sandbox_type' should be 'gvisor'", + "keyActualValue": sprintf("'sandbox_type' is set to '%s'", [resource.node_config.sandbox_config.sandbox_type]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/negative1.tf b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/negative1.tf new file mode 100644 index 00000000000..5a038181abf --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/negative1.tf @@ -0,0 +1,12 @@ +# Caso Negativo 1: Configuración correcta en un clúster principal +resource "google_container_cluster" "pass_cluster" { + name = "secure-main-cluster" + location = "us-central1" + + node_config { + image_type = "COS_CONTAINERD" + sandbox_config { + sandbox_type = "gvisor" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/negative2.tf b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/negative2.tf new file mode 100644 index 00000000000..9bc60d92ffd --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/negative2.tf @@ -0,0 +1,12 @@ +# Caso Negativo 2: Configuración correcta en un pool de nodos independiente +resource "google_container_node_pool" "pass_pool" { + name = "secure-untrusted-pool" + cluster = "my-cluster" + + node_config { + image_type = "COS_CONTAINERD" + sandbox_config { + sandbox_type = "gvisor" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive1.tf new file mode 100644 index 00000000000..b8f9bd1346a --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive1.tf @@ -0,0 +1,9 @@ +resource "google_container_cluster" "fail_cluster_no_sandbox" { + name = "cluster-fail" + location = "us-central1" + + node_config { + machine_type = "e2-medium" + # FALLO: Falta sandbox_config + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive2.tf new file mode 100644 index 00000000000..43a0a1006c9 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive2.tf @@ -0,0 +1,9 @@ +resource "google_container_node_pool" "fail_pool_no_sandbox" { + name = "pool-fail" + cluster = "my-cluster" + + node_config { + machine_type = "e2-medium" + # FALLO: Falta sandbox_config + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive3.tf b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive3.tf new file mode 100644 index 00000000000..65f09f4728b --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive3.tf @@ -0,0 +1,9 @@ +resource "google_container_cluster" "fail_cluster_wrong_type" { + name = "cluster-wrong-type" + + node_config { + sandbox_config { + sandbox_type = "other_runtime" # FALLO: Debe ser gvisor + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive4.tf b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive4.tf new file mode 100644 index 00000000000..f5c36d3aa4d --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive4.tf @@ -0,0 +1,10 @@ +resource "google_container_node_pool" "fail_pool_wrong_type" { + name = "pool-wrong-type" + cluster = "my-cluster" + + node_config { + sandbox_config { + sandbox_type = "disabled" # FALLO: Debe ser gvisor + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..3e0a67ec379 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive_expected_result.json @@ -0,0 +1,26 @@ +[ + { + "queryName": "GKE Sandbox (gVisor) Disabled", + "severity": "LOW", + "line": 5, + "fileName": "positive1.tf" + }, + { + "queryName": "GKE Sandbox (gVisor) Disabled", + "severity": "LOW", + "line": 5, + "fileName": "positive2.tf" + }, + { + "queryName": "GKE Sandbox (gVisor) Disabled", + "severity": "LOW", + "line": 6, + "fileName": "positive3.tf" + }, + { + "queryName": "GKE Sandbox (gVisor) Disabled", + "severity": "LOW", + "line": 7, + "fileName": "positive4.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/README.md b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/README.md new file mode 100644 index 00000000000..499f0c0645d --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/README.md @@ -0,0 +1,50 @@ +# Regla KICS: GKE Secrets Not Encrypted with CMEK + +## Descripción General + +Esta regla de severidad **ALTA** verifica que los clústeres de GKE tengan habilitado el cifrado de secretos en la capa de aplicación mediante una clave de **Cloud KMS** gestionada por el cliente (**CMEK**). + +Por defecto, GKE cifra los datos en reposo a nivel de disco, pero los secretos de Kubernetes almacenados en la base de datos `etcd` requieren una capa de protección adicional. Al habilitar esta función, GKE utiliza una clave de cifrado de sobres (envelope encryption) donde una Clave de Cifrado de Datos (DEK) cifra el secreto, y dicha DEK es cifrada por una Clave de Cifrado de Claves (KEK) alojada en Cloud KMS. Esto permite que el cliente tenga soberanía absoluta sobre sus secretos, pudiendo revocar el acceso a los mismos instantáneamente inhabilitando la clave en KMS. + +## Lógica de la Regla + +La política audita el recurso `google_container_cluster` evaluando tres fallos de seguridad: +1. **Omisión:** No se define el bloque `database_encryption`. +2. **Desactivación:** El estado de cifrado se establece explícitamente en `DECRYPTED`. +3. **Configuración Incompleta:** Se activa el cifrado pero no se proporciona el identificador de la clave (`key_name`). + +## Casos de Fallo Detectados + +--- + +### Caso 1: Configuración de Cifrado Ausente +* **Descripción:** El clúster se aprovisiona sin la capa de protección para secretos en etcd. +* **Ubicación de la Alerta:** Bloque del recurso `google_container_cluster`. + +### Caso 2: Cifrado Deshabilitado +* **Descripción:** Se configura el bloque pero el estado se marca como no cifrado. +* **Ubicación de la Alerta:** Atributo `state` dentro de `database_encryption`. + +### Caso 3: Clave KMS Faltante +* **Descripción:** Se intenta cifrar pero no se referencia ninguna clave válida de Cloud KMS. +* **Ubicación de la Alerta:** Atributo `key_name` dentro de `database_encryption`. + +## Recurso Involucrado + +* `google_container_cluster` + +## Solución + +Configure el bloque `database_encryption` con el estado `ENCRYPTED` y asigne el recurso de clave correspondiente. + +```terraform +resource "google_container_cluster" "secure_cluster" { + name = "production-cluster" + location = "us-central1" + + # Solución técnica + database_encryption { + state = "ENCRYPTED" + key_name = "projects/my-project/locations/global/keyRings/my-ring/cryptoKeys/my-key" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json new file mode 100644 index 00000000000..e577ed16253 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "83d1c89f-e07c-4748-9d96-51a78c49637c", + "queryName": "GKE Secrets Not Encrypted with CMEK", + "severity": "HIGH", + "category": "Encryption", + "descriptionText": "Ensures that GKE clusters have Application-Layer Secrets Encryption enabled using a Cloud KMS key. This protects sensitive data in etcd with a customer-managed encryption key.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_cluster#database_encryption", + "platform": "Terraform", + "descriptionID": "83d1c89f", + "cloudProvider": "gcp", + "cwe": "CWE-312", + "riskScore": 9.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego new file mode 100644 index 00000000000..65cce79b0e4 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego @@ -0,0 +1,52 @@ +package Cx + +# REGLA 1: Bloque 'database_encryption' ausente. +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + not cluster.database_encryption + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'database_encryption' block should be defined", + "keyActualValue": "'database_encryption' block is missing", + } +} + +# REGLA 2: Estado de cifrado incorrecto (DECRYPTED). +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + cluster.database_encryption.state != "ENCRYPTED" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s.database_encryption.state", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'state' should be set to 'ENCRYPTED'", + "keyActualValue": sprintf("'state' is set to '%s'", [cluster.database_encryption.state]), + } +} + +# REGLA 3: Estado ENCRYPTED pero falta el nombre de la clave (key_name). +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + cluster.database_encryption.state == "ENCRYPTED" + + key_name := object.get(cluster.database_encryption, "key_name", "") + key_name == "" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s.database_encryption.key_name", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'key_name' should be defined with a valid KMS key ID", + "keyActualValue": "'key_name' is missing or empty", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/negative1.tf b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/negative1.tf new file mode 100644 index 00000000000..5db9fa37360 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/negative1.tf @@ -0,0 +1,8 @@ +resource "google_container_cluster" "pass_encrypted" { + name = "secure-cluster" + + database_encryption { + state = "ENCRYPTED" + key_name = "projects/p1/locations/global/keyRings/r1/cryptoKeys/k1" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive1.tf new file mode 100644 index 00000000000..ea4cefc36b6 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive1.tf @@ -0,0 +1,5 @@ +resource "google_container_cluster" "fail_missing_block" { + name = "no-encryption-block" + location = "us-central1" + # FALLO: database_encryption no existe +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive2.tf new file mode 100644 index 00000000000..3de90ed7944 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive2.tf @@ -0,0 +1,8 @@ +resource "google_container_cluster" "fail_decrypted" { + name = "explicit-decrypted" + + database_encryption { + state = "DECRYPTED" # FALLO: Debe ser ENCRYPTED + key_name = "" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive3.tf b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive3.tf new file mode 100644 index 00000000000..aa06e7a3f8d --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive3.tf @@ -0,0 +1,8 @@ +resource "google_container_cluster" "fail_missing_key" { + name = "encrypted-no-key" + + # FALLO: Falta key_name + database_encryption { + state = "ENCRYPTED" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..cf68e051c08 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "GKE Secrets Not Encrypted with CMEK", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "GKE Secrets Not Encrypted with CMEK", + "severity": "HIGH", + "line": 5, + "fileName": "positive2.tf" + }, + { + "queryName": "GKE Secrets Not Encrypted with CMEK", + "severity": "HIGH", + "line": 5, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/README.md b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/README.md new file mode 100644 index 00000000000..3080ebf7ef9 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/README.md @@ -0,0 +1,45 @@ +# Regla KICS: GKE Security Posture Disabled (Manual) + +## Descripción General + +Esta regla informativa (**INFO**) de **Observabilidad** verifica si el **Security Posture Dashboard** de GKE está activo en la configuración del clúster. + +El panel de postura de seguridad es una herramienta nativa de Google Cloud que escanea automáticamente las cargas de trabajo de Kubernetes en busca de errores de configuración comunes y vulnerabilidades conocidas en las imágenes de los contenedores. Proporciona recomendaciones accionables para mejorar la seguridad sin añadir complejidad operativa. Dado que la disponibilidad de esta función puede variar según el canal de versiones de GKE y el tipo de licencia (Standard vs Autopilot), esta regla alerta sobre su ausencia para permitir una verificación manual de compatibilidad. + +## Lógica de la Regla + +La política audita el recurso `google_container_cluster` identificando dos escenarios: +1. **Omisión:** El bloque `security_posture_config` no está presente en el código Terraform. +2. **Desactivación:** El bloque existe pero el parámetro `mode` se ha establecido explícitamente como `DISABLED`. + +## Casos de Fallo Detectados + +--- + +### Caso 1: Configuración de Postura Ausente +* **Descripción:** El clúster no ha habilitado el panel de control de seguridad. Se recomienda verificar si la versión de GKE permite su activación. +* **Ubicación de la Alerta:** Nivel de recurso `google_container_cluster`. + +### Caso 2: Modo de Postura Deshabilitado +* **Descripción:** Se ha configurado la postura de seguridad pero se ha desactivado mediante el valor `DISABLED`. +* **Ubicación de la Alerta:** Atributo `mode` dentro de `security_posture_config`. + +## Recurso Involucrado + +* `google_container_cluster` + +## Solución + +Habilite la postura de seguridad configurando el modo en `BASIC` o `ENTERPRISE`. + +```terraform +resource "google_container_cluster" "compliant_cluster" { + name = "monitored-cluster" + location = "us-central1" + + # Solución recomendada para observabilidad de seguridad + security_posture_config { + mode = "BASIC" + vulnerability_mode = "VULNERABILITY_BASIC" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json new file mode 100644 index 00000000000..a119b6d3e04 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "0d688e9b-79a1-4adb-8893-4cae93442ffd", + "queryName": "GKE Security Posture Disabled (Manual)", + "severity": "INFO", + "category": "Observability", + "descriptionText": "GKE Security Posture Dashboard provides visibility into the security status of the cluster. It is not explicitly enabled. Verify if the cluster version supports 'security_posture_config' with mode 'BASIC' or 'ENTERPRISE'.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_cluster#security_posture_config", + "platform": "Terraform", + "descriptionID": "0d688e9b", + "cloudProvider": "gcp", + "cwe": "CWE-1038", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego new file mode 100644 index 00000000000..cfeb14b6cb9 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego @@ -0,0 +1,33 @@ +package Cx + +# REGLA 1: Bloque 'security_posture_config' ausente. +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + not cluster.security_posture_config + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'security_posture_config' block should be defined with mode 'BASIC' or 'ENTERPRISE'", + "keyActualValue": "'security_posture_config' block is missing", + } +} + +# REGLA 2: Bloque presente, pero 'mode' es 'DISABLED'. +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + cluster.security_posture_config.mode == "DISABLED" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s.security_posture_config.mode", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'mode' should be set to 'BASIC' or 'ENTERPRISE'", + "keyActualValue": "'mode' is set to 'DISABLED'", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative1.tf b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative1.tf new file mode 100644 index 00000000000..22015e1b111 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative1.tf @@ -0,0 +1,6 @@ +resource "google_container_cluster" "pass_basic" { + name = "secure-cluster-basic" + security_posture_config { + mode = "BASIC" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative2.tf b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative2.tf new file mode 100644 index 00000000000..efe51b91f0f --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative2.tf @@ -0,0 +1,6 @@ +resource "google_container_cluster" "pass_enterprise" { + name = "secure-cluster-enterprise" + security_posture_config { + mode = "ENTERPRISE" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive1.tf new file mode 100644 index 00000000000..9fef725d35d --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive1.tf @@ -0,0 +1,5 @@ +resource "google_container_cluster" "fail_block_missing" { + name = "cluster-without-posture" + location = "us-central1" + # FALLO: Falta security_posture_config +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive2.tf new file mode 100644 index 00000000000..07f2184f850 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive2.tf @@ -0,0 +1,7 @@ +resource "google_container_cluster" "fail_mode_disabled" { + name = "cluster-posture-off" + + security_posture_config { + mode = "DISABLED" # FALLO: Debe ser BASIC o ENTERPRISE + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..6a757660260 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "GKE Security Posture Disabled (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "GKE Security Posture Disabled (Manual)", + "severity": "INFO", + "line": 5, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/README.md b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/README.md new file mode 100644 index 00000000000..62834eadff2 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/README.md @@ -0,0 +1,54 @@ +# Regla KICS: GKE Workload Identity & Dedicated SA (Manual) + +## Descripción General + +Esta regla informativa (**INFO**) de **Access Control** audita la configuración de identidad para las cargas de trabajo que se ejecutan en **Google Kubernetes Engine (GKE)**. + +La mejor práctica de seguridad para que las aplicaciones de GKE accedan a los servicios de Google Cloud (como Cloud Storage o BigQuery) es utilizar **Workload Identity**. Esta funcionalidad elimina la necesidad de descargar y gestionar claves JSON de cuentas de servicio, vinculando de forma segura una Kubernetes Service Account (KSA) con una Google Service Account (GSA). + +Sin embargo, habilitar la función es solo la mitad del trabajo. Una configuración segura requiere un mapeo **1:1**; si múltiples aplicaciones comparten la misma identidad de Google, un compromiso en una de ellas otorgaría acceso lateral a los recursos de las demás. + +## Lógica de la Regla + +La política audita el recurso `google_container_cluster` en dos fases: +1. **Validación de Función:** Detecta si `workload_identity_config` está ausente, lo que obliga a los Pods a usar la identidad del nodo (riesgo alto). +2. **Auditoría de Gobernanza:** Si la función está activa, alerta al auditor para que verifique manualmente en el código que cada microservicio tiene su propia vinculación dedicada. + +## Casos de Fallo Detectados + +--- + +### Caso 1: Workload Identity Deshabilitado +* **Descripción:** El clúster carece de la infraestructura necesaria para identidades granulares. +* **Ubicación de la Alerta:** Nivel de recurso `google_container_cluster`. + +### Caso 2: Revisión de Mapeo de Identidades +* **Descripción:** La funcionalidad está activa, pero se requiere confirmar que no se están utilizando cuentas de servicio compartidas entre distintos microservicios. +* **Ubicación de la Alerta:** Bloque `workload_identity_config`. + +## Recurso Involucrado + +* `google_container_cluster` + +## Solución + +1. Habilite Workload Identity en su recurso de clúster. +2. Implemente vinculaciones granulares utilizando el rol `roles/iam.workloadIdentityUser`. + +```terraform +resource "google_container_cluster" "compliant_cluster" { + name = "secure-cluster" + location = "us-central1" + + # Habilitar la función + workload_identity_config { + workload_pool = "${var.project_id}.svc.id.goog" + } +} + +# Ejemplo de vinculación manual a verificar (Mapeo 1:1) +resource "google_service_account_iam_member" "dedicated_binding" { + service_account_id = google_service_account.app_specific_sa.name + role = "roles/iam.workloadIdentityUser" + member = "serviceAccount:${var.project_id}.svc.id.goog[namespace/ksa-name]" +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json new file mode 100644 index 00000000000..fb66fe944b8 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "edea054b-6ed2-4be2-bad2-459891848678", + "queryName": "GKE Workload Identity & Dedicated SA (Manual)", + "severity": "INFO", + "category": "Access Control", + "descriptionText": "Ensures that GKE clusters have Workload Identity enabled. If enabled, manual verification is required to ensure that workloads use dedicated Google Service Accounts (1:1 mapping) rather than shared ones.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_cluster#workload_identity_config", + "platform": "Terraform", + "descriptionID": "edea054b", + "cloudProvider": "gcp", + "cwe": "CWE-284", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego new file mode 100644 index 00000000000..d10a078e579 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego @@ -0,0 +1,33 @@ +package Cx + +# REGLA 1: Workload Identity no habilitado (Missing Attribute). +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + not cluster.workload_identity_config + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'workload_identity_config' should be enabled to support dedicated Service Accounts", + "keyActualValue": "'workload_identity_config' is missing", + } +} + +# REGLA 2: Workload Identity habilitado (Verificación Manual de Bindings). +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + cluster.workload_identity_config + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_container_cluster.%s.workload_identity_config", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Verify that workloads use dedicated Service Accounts (no shared SAs)", + "keyActualValue": "Workload Identity is enabled. Manual verification of bindings required.", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/negative1.tf b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/negative1.tf new file mode 100644 index 00000000000..015f1237ef7 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/negative1.tf @@ -0,0 +1,4 @@ +# Caso negativo: No hay clústeres GKE que auditar. +resource "google_compute_network" "vpc" { + name = "main-vpc" +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive1.tf new file mode 100644 index 00000000000..4521fa4170f --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive1.tf @@ -0,0 +1,5 @@ +resource "google_container_cluster" "fail_disabled" { + name = "insecure-cluster" + location = "us-central1" + # FALLO: Falta workload_identity_config +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive2.tf new file mode 100644 index 00000000000..058abb750cc --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive2.tf @@ -0,0 +1,8 @@ +resource "google_container_cluster" "fail_manual_check" { + name = "cluster-with-wi" + + workload_identity_config { + workload_pool = "my-project.svc.id.goog" + } + # INFO: Requiere revisión manual de los bindings de las aplicaciones +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..1c56c81e5e8 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "GKE Workload Identity & Dedicated SA (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "GKE Workload Identity & Dedicated SA (Manual)", + "severity": "INFO", + "line": 4, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/README.md b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/README.md new file mode 100644 index 00000000000..f5e5a8c4375 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/README.md @@ -0,0 +1,47 @@ +# Regla KICS: GCP HTTP(S) Load Balancer Logging Disabled + +## Descripción General + +Esta regla de severidad **MEDIA** verifica que el registro de acceso (Logging) esté habilitado en los recursos `google_compute_backend_service` de Google Cloud. + +Los Backend Services gestionan el tráfico que el balanceador de carga HTTP(S) distribuye hacia los grupos de instancias o buckets. Habilitar los logs de Cloud Armor y del balanceador permite capturar metadatos críticos de cada transacción HTTP: dirección IP de origen, protocolos, latencias de respuesta, y códigos de estado (2xx, 4xx, 5xx). Sin estos registros, la capacidad de respuesta ante incidentes de seguridad (como ataques DoS o inyecciones) y la depuración de errores de infraestructura se ven seriamente limitadas. + +## Lógica de la Regla + +La política audita el recurso `google_compute_backend_service` bajo dos criterios: +1. **Omisión:** Detecta si el bloque `log_config` no ha sido definido. +2. **Desactivación:** Detecta si el atributo `enable` dentro de `log_config` tiene el valor booleano `false`. + +## Casos de Fallo Detectados + +--- + +### Caso 1: Configuración de Logging Ausente +* **Descripción:** El servicio de backend se crea sin parámetros de registro, lo que deshabilita la telemetría de tráfico por defecto. +* **Ubicación de la Alerta:** Nivel de recurso `google_compute_backend_service`. + +### Caso 2: Logging Deshabilitado Explícitamente +* **Descripción:** Se define el bloque de configuración pero se apaga el servicio de logs. +* **Ubicación de la Alerta:** Atributo `enable` dentro de `log_config`. + +## Recurso Involucrado + +* `google_compute_backend_service` + +## Solución + +Añada el bloque `log_config` con el parámetro `enable = true`. Se recomienda un `sample_rate` de `1.0` para producción. + +```terraform +resource "google_compute_backend_service" "compliant_service" { + name = "web-backend-service" + protocol = "HTTP" + port_name = "http" + timeout_sec = 10 + + # Solución técnica + log_config { + enable = true + sample_rate = 1.0 + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json new file mode 100644 index 00000000000..3e26bf5e632 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "0ef3f3f1-0592-475b-b073-81ac1ac869e2", + "queryName": "GCP HTTP(S) Load Balancer Logging Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that logging is enabled for Google Compute Backend Services used in HTTP(S) Load Balancers. Access logs are essential for monitoring traffic patterns, latency, and identifying potential security threats.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_backend_service#log_config", + "platform": "Terraform", + "descriptionID": "0ef3f3f1", + "cloudProvider": "gcp", + "cwe": "CWE-778", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego new file mode 100644 index 00000000000..e15697ad864 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego @@ -0,0 +1,33 @@ +package Cx + +# REGLA 1: Bloque 'log_config' ausente. +CxPolicy[result] { + doc := input.document[i] + bs := doc.resource.google_compute_backend_service[name] + + not bs.log_config + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_compute_backend_service.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "log_config should be defined with enable set to true", + "keyActualValue": "log_config is missing", + } +} + +# REGLA 2: Bloque 'log_config' existe pero 'enable' es false. +CxPolicy[result] { + doc := input.document[i] + bs := doc.resource.google_compute_backend_service[name] + + bs.log_config.enable == false + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_compute_backend_service.%s.log_config.enable", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "log_config.enable should be set to true", + "keyActualValue": "log_config.enable is set to false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/negative1.tf b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/negative1.tf new file mode 100644 index 00000000000..66e55cbbf8c --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/negative1.tf @@ -0,0 +1,8 @@ +resource "google_compute_backend_service" "pass_logs" { + name = "backend-with-logs" + + log_config { + enable = true + sample_rate = 1.0 + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive1.tf b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive1.tf new file mode 100644 index 00000000000..0180ab2193a --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive1.tf @@ -0,0 +1,5 @@ +resource "google_compute_backend_service" "fail_missing_log" { + name = "backend-no-logs" + protocol = "HTTP" + # FALLO: No tiene bloque log_config +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive2.tf b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive2.tf new file mode 100644 index 00000000000..38412e41a49 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive2.tf @@ -0,0 +1,7 @@ +resource "google_compute_backend_service" "fail_disabled_log" { + name = "backend-disabled-logs" + + log_config { + enable = false # FALLO: Debe ser true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..1caf795a721 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "GCP HTTP(S) Load Balancer Logging Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "GCP HTTP(S) Load Balancer Logging Disabled", + "severity": "MEDIUM", + "line": 5, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/README.md b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/README.md new file mode 100644 index 00000000000..d2cc1522d00 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/README.md @@ -0,0 +1,53 @@ +# Regla KICS: IAP Disabled on Backend Service + +## Descripción General + +Esta regla verifica que **Identity-Aware Proxy (IAP)** esté habilitado en los recursos `google_compute_backend_service`. + +IAP es un componente de seguridad Zero Trust que intercepta las solicitudes web enviadas a tu aplicación, autentica al usuario mediante su identidad de Google y solo permite el paso de la solicitud si el usuario está autorizado. + +**Nota sobre Firewall (Manual):** +Habilitar IAP es solo el primer paso. Para cumplir completamente con la normativa de seguridad ("Permitir solo tráfico de Google"), debes configurar manualmente las reglas de firewall de tu VPC para permitir el tráfico **únicamente** desde los rangos de IP de los balanceadores de carga de Google (`130.211.0.0/22` y `35.191.0.0/16`) hacia tus instancias, bloqueando todo el tráfico directo desde Internet. + +## Lógica de la Regla + +La política audita el recurso `google_compute_backend_service`: +1. Verifica si existe el bloque de configuración `iap`. +2. Si el bloque no existe, se considera que el servicio no está protegido por identidad. +3. Verifica que, si el bloque existe, se definan las credenciales necesarias (`oauth2_client_id` y `oauth2_client_secret`). + +## Casos de Fallo Detectados + +### Caso 1: IAP Deshabilitado + +* **Descripción:** El servicio de backend se ha definido sin el bloque `iap`, lo que significa que el tráfico llega directamente (o a través del LB estándar) sin verificación de identidad previa por parte de IAP. +* **Ubicación de la Alerta:** Recurso `google_compute_backend_service`. + +### Caso 2: Cliente ID de OAuth Ausente + +* **Descripción:** El bloque `iap` está presente pero omite el `oauth2_client_id`, impidiendo la autenticación. +* **Ubicación de la Alerta:** Bloque `iap`. + +### Caso 3: Cliente Secret de OAuth Ausente + +* **Descripción:** El bloque `iap` está presente pero omite el `oauth2_client_secret`, impidiendo la autenticación. +* **Ubicación de la Alerta:** Bloque `iap`. + +## Recurso Involucrado + +* `google_compute_backend_service` + +## Solución + +Define el bloque `iap` dentro del servicio de backend e incluye las credenciales de OAuth necesarias. + +```terraform +resource "google_compute_backend_service" "secure" { + name = "iap-backend-service" + health_checks = [google_compute_health_check.default.id] + + iap { + oauth2_client_id = "abc-123.apps.googleusercontent.com" + oauth2_client_secret = "secret-key" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json new file mode 100644 index 00000000000..a9432c792f8 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "3f1222a9-0161-4fe8-b188-ccabaf7a0ba5", + "queryName": "IAP Disabled on Backend Service", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that Identity-Aware Proxy (IAP) is enabled for Google Compute Backend Services. IAP verifies user identity and context before allowing access to applications.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_backend_service#iap", + "platform": "Terraform", + "descriptionID": "3f1222a9", + "cloudProvider": "gcp", + "cwe": "CWE-284", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego new file mode 100644 index 00000000000..7ba18522e71 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego @@ -0,0 +1,51 @@ +package Cx + +# REGLA 1: El bloque 'iap' está ausente en google_compute_backend_service. +CxPolicy[result] { + doc := input.document[i] + bs := doc.resource.google_compute_backend_service[name] + + not bs.iap + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_compute_backend_service.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'google_compute_backend_service.%s' should have an 'iap' block defined", [name]), + "keyActualValue": sprintf("'google_compute_backend_service.%s' is missing the 'iap' block", [name]), + } +} + +# REGLA 2: El bloque 'iap' existe pero falta 'oauth2_client_id'. +CxPolicy[result] { + doc := input.document[i] + bs := doc.resource.google_compute_backend_service[name] + + bs.iap + not bs.iap.oauth2_client_id + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_compute_backend_service.%s.iap", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'oauth2_client_id' should be defined within the 'iap' block", + "keyActualValue": "'oauth2_client_id' is missing", + } +} + +# REGLA 3: El bloque 'iap' existe pero falta 'oauth2_client_secret'. +CxPolicy[result] { + doc := input.document[i] + bs := doc.resource.google_compute_backend_service[name] + + bs.iap + not bs.iap.oauth2_client_secret + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_compute_backend_service.%s.iap", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'oauth2_client_secret' should be defined within the 'iap' block", + "keyActualValue": "'oauth2_client_secret' is missing", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/negative1.tf b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/negative1.tf new file mode 100644 index 00000000000..1d225647a1a --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/negative1.tf @@ -0,0 +1,8 @@ +resource "google_compute_backend_service" "pass_secure" { + name = "fully-secure-service" + + iap { + oauth2_client_id = "client-id" + oauth2_client_secret = "secret-val" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive1.tf b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive1.tf new file mode 100644 index 00000000000..054d5dd2c75 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive1.tf @@ -0,0 +1,4 @@ +resource "google_compute_backend_service" "fail_no_iap" { + name = "no-iap-service" + health_checks = ["check-id"] +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive2.tf b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive2.tf new file mode 100644 index 00000000000..a83e39a3ac1 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive2.tf @@ -0,0 +1,6 @@ +resource "google_compute_backend_service" "fail_no_id" { + name = "no-client-id" + iap { + oauth2_client_secret = "some-secret" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive3.tf b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive3.tf new file mode 100644 index 00000000000..33eb97d6db4 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive3.tf @@ -0,0 +1,6 @@ +resource "google_compute_backend_service" "fail_no_secret" { + name = "no-client-secret" + iap { + oauth2_client_id = "some-id" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..89832969a28 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "IAP Disabled on Backend Service", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "IAP Disabled on Backend Service", + "severity": "MEDIUM", + "line": 3, + "fileName": "positive2.tf" + }, + { + "queryName": "IAP Disabled on Backend Service", + "severity": "MEDIUM", + "line": 3, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/README.md b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/README.md new file mode 100644 index 00000000000..ccb1f2e6d79 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/README.md @@ -0,0 +1,40 @@ +# Regla KICS: Cloud SQL PostgreSQL log_error_verbosity is Verbose + +## Descripción General + +Esta regla verifica la configuración del flag de base de datos `log_error_verbosity` en instancias de **Google Cloud SQL (PostgreSQL)**. + +Este parámetro controla la cantidad de detalles que se escriben en el registro de errores del servidor. El nivel `verbose` incluye información interna como código fuente y números de línea, lo cual no es recomendado para entornos de producción por motivos de seguridad y rendimiento. + +## Lógica de la Regla + +La política inspecciona el recurso `google_sql_database_instance`: +1. Verifica si la versión de la base de datos contiene "POSTGRES". +2. Normaliza el bloque `settings.database_flags` para procesar correctamente tanto configuraciones con un único flag como con múltiples. +3. Si encuentra un flag llamado `log_error_verbosity` con el valor `verbose`, genera una alerta. + +## Casos de Fallo Detectados + +### Caso 1: Verbosity Insegura + +* **Descripción:** El flag está explícitamente configurado como `verbose`. +* **Ubicación de la Alerta:** Bloque `database_flags`. + +## Recurso Involucrado + +* `google_sql_database_instance` + +## Solución + +Establece el valor en `default`, `terse` o elimina el flag. + +```terraform +resource "google_sql_database_instance" "secure" { + database_version = "POSTGRES_14" + settings { + database_flags { + name = "log_error_verbosity" + value = "default" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json new file mode 100644 index 00000000000..ac5563b73c0 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "80d98d7b-2f12-4a8c-8cc9-fd17ca19c569", + "queryName": "Cloud SQL PostgreSQL log_error_verbosity is Verbose", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that the 'log_error_verbosity' flag for Cloud SQL PostgreSQL instances is set to 'default' or 'terse'. Setting it to 'verbose' generates excessive logs containing internal source code details, which can be a security risk.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance", + "platform": "Terraform", + "descriptionID": "80d98d7b", + "cloudProvider": "gcp", + "cwe": "CWE-532", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego new file mode 100644 index 00000000000..080bfd7bc97 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego @@ -0,0 +1,25 @@ +package Cx + +ensure_array(x) = x { is_array(x) } +ensure_array(x) = [x] { is_object(x) } + +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_sql_database_instance[name] + + contains(resource.database_version, "POSTGRES") + + flags := ensure_array(resource.settings.database_flags) + flag := flags[j] + + flag.name == "log_error_verbosity" + lower(flag.value) == "verbose" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_sql_database_instance.%s.settings.database_flags", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'log_error_verbosity' should be set to 'default' or 'terse'", + "keyActualValue": sprintf("'log_error_verbosity' is set to '%s'", [flag.value]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/negative1.tf b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/negative1.tf new file mode 100644 index 00000000000..7d68bad7488 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/negative1.tf @@ -0,0 +1,11 @@ +resource "google_sql_database_instance" "pass" { + name = "postgres-ok" + database_version = "POSTGRES_14" + + settings { + database_flags { + name = "log_error_verbosity" + value = "default" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive1.tf b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive1.tf new file mode 100644 index 00000000000..78036f66a5e --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive1.tf @@ -0,0 +1,12 @@ +resource "google_sql_database_instance" "fail_single" { + name = "postgres-single-flag" + database_version = "POSTGRES_14" + + settings { + tier = "db-f1-micro" + database_flags { + name = "log_error_verbosity" + value = "verbose" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive2.tf b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive2.tf new file mode 100644 index 00000000000..d8092b0e90f --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive2.tf @@ -0,0 +1,18 @@ +resource "google_sql_database_instance" "fail_multiple" { + name = "postgres-multiple-flags" + database_version = "POSTGRES_14" + + settings { + tier = "db-f1-micro" + + database_flags { + name = "log_connections" + value = "on" + } + + database_flags { + name = "log_error_verbosity" + value = "verbose" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive_expected_result.json new file mode 100644 index 00000000000..1f14d5137b6 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Cloud SQL PostgreSQL log_error_verbosity is Verbose", + "severity": "MEDIUM", + "line": 7, + "fileName": "positive1.tf" + }, + { + "queryName": "Cloud SQL PostgreSQL log_error_verbosity is Verbose", + "severity": "MEDIUM", + "line": 8, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/README.md b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/README.md new file mode 100644 index 00000000000..25aed51b502 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/README.md @@ -0,0 +1,51 @@ +# Regla KICS: Cloud SQL PostgreSQL log_statement Improperly Set + +## Descripción General + +Esta regla verifica la configuración del flag `log_statement` en instancias de **Google Cloud SQL (PostgreSQL)**. + +Este parámetro controla qué sentencias SQL se registran en los logs del servidor: +* **`none`:** No registra ninguna sentencia (Default). +* **`ddl`:** Registra sentencias de definición de datos (CREATE, ALTER, DROP). Recomendado por CIS Benchmark como línea base. +* **`mod`:** Registra DDL y sentencias de modificación de datos (INSERT, UPDATE, DELETE). +* **`all`:** Registra todas las sentencias. + +Para cumplir con normativas de auditoría y seguridad, se debe configurar al menos en `ddl` para rastrear cambios estructurales en la base de datos que podrían comprometer la integridad de la misma. + +## Lógica de la Regla + +La política evalúa el recurso `google_sql_database_instance` (PostgreSQL): +1. **Flag Ausente:** Si `log_statement` no se encuentra dentro de la lista de flags configurados, falla (ya que el valor por defecto de PostgreSQL es insuficiente para auditoría). +2. **Flag Incorrecto:** Si `log_statement` está presente pero su valor es explícitamente `none`, falla. + +## Casos de Fallo Detectados + +### Caso 1: Configuración Ausente +* **Descripción:** No se ha definido el flag, por lo que la base de datos no está auditando sentencias críticas. +* **Ubicación de la Alerta:** Bloque `database_flags`. + +### Caso 2: Auditoría Deshabilitada Explícitamente +* **Descripción:** El flag está configurado con el valor `none`, desactivando el registro de sentencias. +* **Ubicación de la Alerta:** Bloque `database_flags`. + +## Recurso Involucrado + +* `google_sql_database_instance` + +## Solución + +Establezca el valor del flag `log_statement` en `ddl` (mínimo recomendado para auditoría), `mod` o `all`. + +```terraform +resource "google_sql_database_instance" "secure" { + name = "secure-postgresql" + database_version = "POSTGRES_14" + region = "us-central1" + + settings { + database_flags { + name = "log_statement" + value = "ddl" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json new file mode 100644 index 00000000000..46a857f7d7b --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "ede2d9e4-d3a6-4751-a89b-561bc9bacbe4", + "queryName": "Cloud SQL PostgreSQL log_statement Improperly Set", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that the 'log_statement' database flag for Cloud SQL PostgreSQL instances is set to 'ddl', 'mod', or 'all'. The default value is 'none', which disables statement logging and hinders auditing capability.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance", + "platform": "Terraform", + "descriptionID": "ede2d9e4", + "cloudProvider": "gcp", + "cwe": "CWE-778", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego new file mode 100644 index 00000000000..a8fc36e8108 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego @@ -0,0 +1,49 @@ +package Cx + +ensure_array(x) = x { is_array(x) } +ensure_array(x) = [x] { is_object(x) } + +has_log_statement(flags_list) { + flag := flags_list[_] + flag.name == "log_statement" +} + +# REGLA 1: El flag 'log_statement' no está definido (Ausente). +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_sql_database_instance[name] + + contains(resource.database_version, "POSTGRES") + + flags_list := ensure_array(resource.settings.database_flags) + not has_log_statement(flags_list) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_sql_database_instance.%s.settings.database_flags", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'database_flags' should include 'log_statement' set to 'ddl', 'mod', or 'all'", + "keyActualValue": "'log_statement' flag is missing (defaults to 'none')", + } +} + +# REGLA 2: El flag 'log_statement' existe pero está en 'none'. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_sql_database_instance[name] + + contains(resource.database_version, "POSTGRES") + + flags_list := ensure_array(resource.settings.database_flags) + flag := flags_list[_] + flag.name == "log_statement" + lower(flag.value) == "none" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.google_sql_database_instance.%s.settings.database_flags", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'log_statement' should be set to 'ddl', 'mod', or 'all'", + "keyActualValue": "'log_statement' is set to 'none'", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/negative1.tf b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/negative1.tf new file mode 100644 index 00000000000..f399c7b136c --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/negative1.tf @@ -0,0 +1,11 @@ +# Caso Pass: Valor DDL +resource "google_sql_database_instance" "pass_ddl" { + name = "postgres-ok-ddl" + database_version = "POSTGRES_13" + settings { + database_flags { + name = "log_statement" + value = "ddl" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive1.tf b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive1.tf new file mode 100644 index 00000000000..3816f570485 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive1.tf @@ -0,0 +1,12 @@ +resource "google_sql_database_instance" "fail_missing_flag" { + name = "postgres-no-audit" + database_version = "POSTGRES_13" + + settings { + tier = "db-f1-micro" + database_flags { + name = "log_connections" + value = "on" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive2.tf b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive2.tf new file mode 100644 index 00000000000..74e7691edcc --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive2.tf @@ -0,0 +1,11 @@ +resource "google_sql_database_instance" "fail_explicit_none" { + name = "postgres-none-audit" + database_version = "POSTGRES_14" + + settings { + database_flags { + name = "log_statement" + value = "none" # FALLO + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive_expected_result.json new file mode 100644 index 00000000000..dd142772ba1 --- /dev/null +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Cloud SQL PostgreSQL log_statement Improperly Set", + "severity": "MEDIUM", + "line": 7, + "fileName": "positive1.tf" + }, + { + "queryName": "Cloud SQL PostgreSQL log_statement Improperly Set", + "severity": "MEDIUM", + "line": 6, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/README.md b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/README.md new file mode 100644 index 00000000000..e0bac430cd4 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/README.md @@ -0,0 +1,65 @@ +# Regla KICS: Log de Auditoría para IBM Cloud IAM (Activity Tracker) + +## Descripción General + +Esta regla de KICS para Terraform asegura que una instancia de IBM Cloud Activity Tracker esté configurada para capturar eventos de auditoría, especialmente los eventos globales relacionados con la gestión de identidades y accesos (IAM). + +IBM Cloud genera eventos de auditoría para acciones críticas en la cuenta (creación de usuarios, cambios de políticas, etc.). Para que estos eventos sean registrados y retenidos, se debe provisionar un servicio `activity-tracker`. Además, para capturar eventos que ocurren a nivel de cuenta (globales), la instancia de Activity Tracker debe estar ubicada en una región específica designada por IBM como "región de eventos globales". Sin esta configuración, las acciones de los administradores sobre IAM podrían no quedar registradas, dificultando investigaciones forenses o auditorías de cumplimiento. + +## Lógica de la Regla + +La política se compone de dos reglas que verifican la configuración de Activity Tracker: +1. **Validación Global:** Confirma que al menos una instancia de `activity-tracker` exista en la configuración. +2. **Validación de Ubicación:** Si existen instancias, confirma que su atributo `location` corresponda a una región compatible con eventos globales. Las regiones soportadas son: `eu-de` (Frankfurt), `eu-gb` (Londres), `us-south` (Dallas) y `au-syd` (Sídney). + +## Casos de Fallo Detectados + +A continuación se describen los dos escenarios que esta política detectará. + +--- + +### Caso 1: Instancia de `activity-tracker` Ausente + +* **Descripción:** Esta regla se activa si no existe ningún recurso `ibm_resource_instance` en la configuración de Terraform que tenga el atributo `service` configurado como `"activity-tracker"`. Esto significa que no se está capturando ningún log de auditoría en la cuenta. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + # El proyecto contiene varios recursos, pero ninguno define el servicio 'activity-tracker'. + resource "ibm_is_vpc" "example" { + name = "my-vpc" + } + ``` +* **Ubicación de la Alerta:** La alerta será general y se anclará al bloque `provider "ibm" {}` indicando la ausencia del recurso. + +--- + +### Caso 2: Instancia en una Región de Eventos Globales Incorrecta + +* **Descripción:** Esta regla se activa si el recurso `activity-tracker` tiene su atributo `location` configurado en una región que no está designada por IBM para recibir eventos globales. Esto resultaría en la pérdida de visibilidad sobre los eventos de IAM. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_resource_instance" "activity_tracker_wrong_region" { + name = "my-activity-tracker" + service = "activity-tracker" + plan = "lite" + location = "us-east" # <-- ¡PROBLEMA! No es una región de eventos globales. + } + ``` +* **Ubicación de la Alerta:** La alerta señalará específicamente al atributo `location` de la instancia de Activity Tracker incorrecta. + +## Recurso Involucrado + +* `ibm_resource_instance` + +## Solución + +Para solucionar los problemas detectados, asegúrate de que exista al menos un recurso `ibm_resource_instance` para el servicio `activity-tracker` y que su atributo `location` esté configurado en una de las regiones de eventos globales soportadas (Frankfurt, Londres, Dallas o Sídney). + +```terraform +resource "ibm_resource_instance" "activity_tracker_correct" { + name = "my-global-activity-tracker" + service = "activity-tracker" + plan = "lite" + + # 'eu-de' es una de las regiones que soportan eventos globales. + location = "eu-de" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json new file mode 100644 index 00000000000..55ea8278a4b --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "479bbdfd-342a-4121-8844-7387eea26d96", + "queryName": "Activity Tracker for Global Events Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that an IBM Cloud Activity Tracker instance is provisioned to capture IAM and other global account events. For compliance and security, at least one instance must be configured in a region that supports receiving global events.", + "descriptionUrl": "https://cloud.ibm.com/docs/activity-tracker?topic=activity-tracker-global-events", + "platform": "Terraform", + "descriptionID": "479bbdfd", + "cloudProvider": "ibm", + "cwe": "CWE-778", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego new file mode 100644 index 00000000000..2f71acd96dd --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego @@ -0,0 +1,40 @@ +package Cx + +# REGLA 1: No existe ningún recurso 'ibm_resource_instance' para 'activity-tracker'. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.ibm + + all_activity_trackers := [tracker | + tracker := input.document[_].resource.ibm_resource_instance[_] + tracker.service == "activity-tracker" + ] + + count(all_activity_trackers) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.ibm", + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'ibm_resource_instance' with service='activity-tracker' should exist", + "keyActualValue": "No 'ibm_resource_instance' for service 'activity-tracker' was found", + } +} + +# REGLA 2: Una instancia de 'activity-tracker' está en una región incorrecta para eventos globales. +CxPolicy[result] { + global_event_regions := {"eu-de", "eu-gb", "us-south", "au-syd"} + + tracker := input.document[i].resource.ibm_resource_instance[tracker_name] + tracker.service == "activity-tracker" + + not global_event_regions[tracker.location] + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_resource_instance.%s.location", [tracker_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Activity Tracker 'location' should be a global event region (e.g., 'eu-de', 'us-south')", + "keyActualValue": sprintf("Activity Tracker 'location' is '%s', which is not a global event region", [tracker.location]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/negative1.tf b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/negative1.tf new file mode 100644 index 00000000000..2854dd08df0 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/negative1.tf @@ -0,0 +1,10 @@ +provider "ibm" { + region = "us-south" +} + +resource "ibm_resource_instance" "tracker_correct" { + name = "global-tracker" + service = "activity-tracker" + plan = "7-day" + location = "us-south" # CORRECTO: Región de eventos globales (Dallas) +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive1.tf b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive1.tf new file mode 100644 index 00000000000..92c27402faf --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive1.tf @@ -0,0 +1,7 @@ +provider "ibm" { + region = "us-south" +} + +resource "ibm_is_vpc" "example_vpc" { + name = "production-vpc" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive2.tf b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive2.tf new file mode 100644 index 00000000000..ca284ef7a48 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive2.tf @@ -0,0 +1,10 @@ +provider "ibm" { + region = "us-south" +} + +resource "ibm_resource_instance" "tracker_wrong_location" { + name = "regional-tracker" + service = "activity-tracker" + plan = "lite" + location = "us-east" # FALLO: No soporta eventos globales +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..04f21d98a44 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Activity Tracker for Global Events Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Activity Tracker for Global Events Disabled", + "severity": "MEDIUM", + "line": 9, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/README.md b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/README.md new file mode 100644 index 00000000000..8bb0d4d359e --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/README.md @@ -0,0 +1,86 @@ +# Regla KICS: Logs de Plataforma Habilitados en Activity Tracker + +## Descripción General + +Esta regla de KICS para Terraform asegura que el servicio IBM Cloud Activity Tracker esté configurado para recibir y registrar los logs de gestión de la plataforma. + +Los logs de plataforma (`platform_logs`) capturan eventos críticos a nivel de cuenta, como la gestión de usuarios y accesos (IAM), la facturación y la modificación de recursos, que son esenciales para una auditoría de seguridad completa y el cumplimiento normativo. Si esta opción no está habilitada, se pierde visibilidad sobre las acciones más importantes que ocurren en la cuenta, dejando puntos ciegos en la monitorización de seguridad. + +## Lógica de la Regla + +La política se divide en tres reglas especializadas para cubrir todos los escenarios en los que los logs de plataforma no están habilitados: +1. **Existencia Global:** Verifica que al menos un Activity Tracker esté provisionado en la cuenta. +2. **Atributo Faltante:** Verifica que el atributo `platform_logs` esté definido (ya que por defecto es `false`). +3. **Valor Incorrecto:** Verifica que el atributo no esté explícitamente desactivado. + +## Casos de Fallo Detectados + +A continuación se describen los tres escenarios que esta política detectará. + +--- + +### Caso 1: Instancia de `activity-tracker` Ausente + +* **Descripción:** Esta regla se activa si no existe ningún recurso `ibm_resource_instance` con `service = "activity-tracker"`. Sin esta instancia, no hay ningún servicio que pueda recopilar los logs de la plataforma. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + # El proyecto de Terraform no define ninguna instancia para el servicio 'activity-tracker'. + resource "ibm_is_vpc" "example" { + name = "my-vpc" + } + ``` +* **Ubicación de la Alerta:** La alerta será general y se anclará al bloque `provider "ibm" {}` para indicar que falta un recurso `activity-tracker` en la configuración global. + +--- + +### Caso 2: Atributo `platform_logs` Ausente + +* **Descripción:** Esta regla detecta una instancia de `activity-tracker` que existe, pero a la que le falta el atributo `platform_logs`. Según la documentación de Terraform para IBM Cloud, el valor por defecto de este atributo es `false`, por lo que su ausencia constituye una configuración insegura. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_resource_instance" "tracker_missing_attribute" { + name = "my-activity-tracker" + service = "activity-tracker" + plan = "lite" + location = "eu-de" + + # El atributo 'platform_logs' no está presente. + } + ``` +* **Ubicación de la Alerta:** La alerta señalará directamente al bloque del recurso `ibm_resource_instance` al que le falta el atributo. + +--- + +### Caso 3: Atributo `platform_logs` es `false` + +* **Descripción:** Esta regla busca una instancia de `activity-tracker` que tiene el atributo `platform_logs` explícitamente configurado como `false`. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_resource_instance" "tracker_disabled_explicitly" { + name = "my-activity-tracker" + service = "activity-tracker" + plan = "lite" + location = "eu-de" + + platform_logs = false # <-- ¡PROBLEMA! + } + ``` +* **Ubicación de la Alerta:** La alerta señalará específicamente a la línea `platform_logs = false` dentro del recurso `ibm_resource_instance`. + +## Recurso Involucrado + +* `ibm_resource_instance` + +## Solución + +Para solucionar los problemas detectados, asegúrate de que exista al menos un recurso `ibm_resource_instance` para el servicio `activity-tracker` y que incluya la siguiente línea: + +```terraform +resource "ibm_resource_instance" "activity_tracker_correct" { + name = "my-activity-tracker" + service = "activity-tracker" + plan = "lite" + location = "eu-de" # Región compatible con eventos globales + + platform_logs = true +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json new file mode 100644 index 00000000000..9f93f69fbc2 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "ccf65fe5-85f2-414d-b68e-b5101bc4bc03", + "queryName": "Activity Tracker Platform Logs Disabled", + "severity": "HIGH", + "category": "Observability", + "descriptionText": "Ensures that the IBM Cloud Activity Tracker instance is configured to receive platform logs. Capturing platform management events is critical for security auditing, threat detection, and compliance.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_instance#platform_logs", + "platform": "Terraform", + "descriptionID": "ccf65fe5", + "cloudProvider": "ibm", + "cwe": "CWE-778", + "riskScore": 6.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego new file mode 100644 index 00000000000..7fb022a7f88 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego @@ -0,0 +1,54 @@ +package Cx + +# REGLA 1: No existe ningún recurso 'ibm_resource_instance' para el servicio 'activity-tracker'. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.ibm + + all_activity_trackers := [tracker | + tracker := input.document[_].resource.ibm_resource_instance[_] + tracker.service == "activity-tracker" + ] + + count(all_activity_trackers) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.ibm", + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'ibm_resource_instance' with service='activity-tracker' should exist", + "keyActualValue": "No 'ibm_resource_instance' for service 'activity-tracker' was found", + } +} + +# REGLA 2: El atributo 'platform_logs' está ausente en la instancia de Activity Tracker. +CxPolicy[result] { + tracker := input.document[i].resource.ibm_resource_instance[tracker_name] + tracker.service == "activity-tracker" + + object.get(tracker, "platform_logs", null) == null + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_resource_instance.%s", [tracker_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'platform_logs' attribute should be present and set to 'true'", + "keyActualValue": "'platform_logs' attribute is missing and defaults to 'false'", + } +} + +# REGLA 3: El atributo 'platform_logs' está explícitamente configurado como 'false'. +CxPolicy[result] { + tracker := input.document[i].resource.ibm_resource_instance[tracker_name] + tracker.service == "activity-tracker" + + tracker.platform_logs == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_resource_instance.%s.platform_logs", [tracker_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'platform_logs' attribute should be 'true'", + "keyActualValue": "'platform_logs' attribute is 'false'", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/negative1.tf b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/negative1.tf new file mode 100644 index 00000000000..5500054ac55 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/negative1.tf @@ -0,0 +1,11 @@ +provider "ibm" { + region = "eu-de" +} + +resource "ibm_resource_instance" "tracker_compliant" { + name = "activity-tracker-secure" + service = "activity-tracker" + plan = "7-day" + location = "eu-de" + platform_logs = true +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive1.tf b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive1.tf new file mode 100644 index 00000000000..341279abc94 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive1.tf @@ -0,0 +1,8 @@ +provider "ibm" { + region = "eu-de" +} + +# No hay activity-tracker +resource "ibm_is_vpc" "vpc_test" { + name = "test-vpc" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive2.tf b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive2.tf new file mode 100644 index 00000000000..6094a5408a3 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive2.tf @@ -0,0 +1,11 @@ +provider "ibm" { + region = "eu-de" +} + +resource "ibm_resource_instance" "tracker_no_attr" { + name = "activity-tracker-missing" + service = "activity-tracker" + plan = "lite" + location = "eu-de" + # FALLO: Falta platform_logs +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive3.tf b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive3.tf new file mode 100644 index 00000000000..a0da5210e4a --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive3.tf @@ -0,0 +1,13 @@ +provider "ibm" { + region = "eu-de" +} + +resource "ibm_resource_instance" "tracker_disabled" { + name = "activity-tracker-off" + service = "activity-tracker" + plan = "lite" + location = "eu-de" + + # FALLO: Deshabilitado explícitamente + platform_logs = false +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..ebcb1e4e1b0 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Activity Tracker Platform Logs Disabled", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Activity Tracker Platform Logs Disabled", + "severity": "HIGH", + "line": 5, + "fileName": "positive2.tf" + }, + { + "queryName": "Activity Tracker Platform Logs Disabled", + "severity": "HIGH", + "line": 12, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/README.md b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/README.md new file mode 100644 index 00000000000..bd44b061a45 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/README.md @@ -0,0 +1,58 @@ +# Regla KICS: IBM Block Storage Encryption (CMK/BYOK/KYOK) Manual + +## Descripción General + +Esta regla unificada (INFO) audita los volúmenes de almacenamiento en bloque (`ibm_is_volume`) en IBM Cloud VPC para asegurar que utilizan estrategias de cifrado gestionadas por el cliente. + +Cubre tres controles de seguridad distintos pero técnicamente equivalentes en la configuración de Terraform: +1. **CMK (Customer Managed Key):** Uso de claves raíz almacenadas en Key Protect estándar. +2. **BYOK (Bring Your Own Key):** Uso de material de clave generado por el cliente e importado a IBM Cloud. +3. **KYOK (Keep Your Own Key):** Uso de Hyper Protect Crypto Services (HSM dedicado con certificación FIPS 140-2 Nivel 4). + +La presencia del argumento `encryption_key` es el requisito técnico indispensable para habilitar cualquiera de estos tres modelos de control de claves sobre el almacenamiento. + +## Lógica de la Regla + +La política realiza las siguientes comprobaciones: +1. Identifica todos los recursos de tipo `ibm_is_volume`. +2. Verifica si el atributo `encryption_key` está ausente en la definición del recurso. +3. Si falta, genera una alerta informativa indicando que el volumen está utilizando el cifrado por defecto (claves gestionadas por IBM), lo cual puede no satisfacer requisitos de cumplimiento de alto nivel. + +## Casos de Fallo Detectados + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso 1: Cifrado por Defecto (Provider-Managed) + +* **Descripción:** El volumen de bloque ha sido definido sin asignar una clave de cifrado específica. Aunque los datos están cifrados en reposo, las claves son controladas automáticamente por IBM Cloud. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_is_volume" "example_default_enc" { + name = "my-volume" + profile = "10iops-tier" + zone = "us-south-1" + + # Falta el atributo 'encryption_key' + } + ``` +* **Ubicación de la Alerta:** La alerta señalará directamente al bloque del recurso `ibm_is_volume`. + +## Recurso Involucrado + +* `ibm_is_volume` + +## Solución + +Para cumplir con políticas de CMK, BYOK o KYOK, debes asignar el CRN (Cloud Resource Name) de una clave raíz válida proveniente de Key Protect o Hyper Protect Crypto Services. + +```terraform +resource "ibm_is_volume" "secure_volume" { + name = "data-volume" + profile = "general-purpose" + zone = "us-south-1" + + # Habilitar Cifrado por el Cliente (Cubre CMK, BYOK y KYOK) + encryption_key = "crn:v1:bluemix:public:kms:us-south:a/aaaaaa:bbbbbb:key:cccccc" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json new file mode 100644 index 00000000000..b6962cab19c --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "56cd75da-f919-4350-8b32-1d0e4313e965", + "queryName": "IBM Block Storage Encryption (CMK/BYOK/KYOK) Manual", + "severity": "INFO", + "category": "Encryption", + "descriptionText": "The Block Storage volume uses default provider-managed encryption. It is not configured with 'encryption_key', which is required for Customer Managed Keys (CMK), Bring Your Own Key (BYOK), or Keep Your Own Key (KYOK). Manual verification of the key source is required.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_volume", + "platform": "Terraform", + "descriptionID": "56cd75da", + "cloudProvider": "ibm", + "cwe": "CWE-312", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/query.rego b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/query.rego new file mode 100644 index 00000000000..690198eefdc --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/query.rego @@ -0,0 +1,17 @@ +package Cx + +# REGLA UNIFICADA: Cifrado Gestionado por el Cliente en Block Storage. +CxPolicy[result] { + doc := input.document[i] + volume := doc.resource.ibm_is_volume[name] + + object.get(volume, "encryption_key", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_is_volume.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'encryption_key' attribute should be defined (prerequisite for CMK, BYOK, or KYOK)", + "keyActualValue": "'encryption_key' is missing (using default provider-managed encryption)", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/negative1.tf b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/negative1.tf new file mode 100644 index 00000000000..8e5181710a7 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/negative1.tf @@ -0,0 +1,12 @@ +provider "ibm" { + region = "us-south" +} + +resource "ibm_is_volume" "volume_secure" { + name = "secure-volume" + profile = "general-purpose" + zone = "us-south-1" + + # CORRECTO: Se define una clave de cifrado + encryption_key = "crn:v1:bluemix:public:kms:us-south:a/test:test:key:test" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive1.tf b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive1.tf new file mode 100644 index 00000000000..aa5e37d06c0 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive1.tf @@ -0,0 +1,10 @@ +provider "ibm" { + region = "us-south" +} + +resource "ibm_is_volume" "volume_insecure" { + name = "insecure-volume" + profile = "general-purpose" + zone = "us-south-1" + # FALLO: Falta el atributo encryption_key +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive_expected_result.json new file mode 100644 index 00000000000..a9e0734f996 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "IBM Block Storage Encryption (CMK/BYOK/KYOK) Manual", + "severity": "INFO", + "line": 5, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/README.md b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/README.md new file mode 100644 index 00000000000..8c432427f2c --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/README.md @@ -0,0 +1,65 @@ +# Regla KICS: Renovación Automática Habilitada para Certificados + +## Descripción General + +Esta regla de KICS para Terraform asegura que todos los certificados gestionados a través de IBM Cloud Certificate Manager (`ibm_cm_certificate`) tengan habilitada la funcionalidad de renovación automática. + +La gestión manual de la caducidad de los certificados TLS es propensa a errores humanos, que pueden resultar en la caducidad de un certificado y causar interrupciones de servicio, errores de confianza y riesgos de seguridad. La renovación automática es una práctica recomendada para garantizar la continuidad del servicio y reducir la carga operativa de mantenimiento de seguridad. + +## Lógica de la Regla + +La política se compone de dos reglas especializadas para cubrir los casos en los que la renovación automática no está habilitada: +1. **Atributo Faltante:** Identifica recursos donde no se define `auto_renew_enabled`, heredando el valor por defecto inseguro (`false`). +2. **Valor Incorrecto:** Identifica recursos donde se ha desactivado explícitamente la renovación automática. + +## Casos de Fallo Detectados + +A continuación se describen los dos escenarios que esta política detectará. + +--- + +### Caso 1: Atributo `auto_renew_enabled` Ausente + +* **Descripción:** Esta regla detecta cualquier recurso `ibm_cm_certificate` donde el atributo `auto_renew_enabled` no está definido. Según la documentación del proveedor de Terraform para IBM, el valor por defecto de este atributo es `false`. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_cm_certificate" "cert_renew_missing" { + instance_id = ibm_resource_instance.cm_instance.guid + name = "my-cert-renew-missing" + + # El atributo 'auto_renew_enabled' no está presente. + } + ``` +* **Ubicación de la Alerta:** La alerta señalará directamente al bloque de código del recurso `ibm_cm_certificate` al que le falta el atributo. + +--- + +### Caso 2: Atributo `auto_renew_enabled` es `false` + +* **Descripción:** Esta regla busca un recurso `ibm_cm_certificate` que tiene el atributo `auto_renew_enabled` explícitamente configurado como `false`. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_cm_certificate" "cert_renew_disabled" { + instance_id = ibm_resource_instance.cm_instance.guid + name = "my-cert-renew-disabled" + + auto_renew_enabled = false # <-- ¡PROBLEMA! + } + ``` +* **Ubicación de la Alerta:** La alerta señalará específicamente a la línea `auto_renew_enabled = false` dentro del recurso `ibm_cm_certificate`. + +## Recurso Involucrado + +* `ibm_cm_certificate` + +## Solución + +Para solucionar los problemas detectados por esta regla, asegúrate de que cada recurso `ibm_cm_certificate` incluya el atributo habilitado: + +```terraform +resource "ibm_cm_certificate" "cert_correct" { + instance_id = ibm_resource_instance.cm_instance.guid + name = "my-secure-certificate" + + auto_renew_enabled = true +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json new file mode 100644 index 00000000000..71ce8c750b8 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "6797782b-0523-4419-9297-1747e1bf82ab", + "queryName": "Certificate Manager Auto Renew Disabled", + "severity": "MEDIUM", + "category": "Best Practices", + "descriptionText": "Ensures that certificates managed by IBM Cloud Certificate Manager are configured to renew automatically before expiration. Disabling auto-renewal can lead to service disruptions and security risks due to expired certificates.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/cm_certificate#auto_renew_enabled", + "platform": "Terraform", + "descriptionID": "6797782b", + "cloudProvider": "ibm", + "cwe": "CWE-320", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/query.rego b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/query.rego new file mode 100644 index 00000000000..9a54f0dae44 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/query.rego @@ -0,0 +1,33 @@ +package Cx + +# REGLA 1: El atributo 'auto_renew_enabled' está ausente en el certificado. +CxPolicy[result] { + doc := input.document[i] + certificate := doc.resource.ibm_cm_certificate[cert_name] + + object.get(certificate, "auto_renew_enabled", null) == null + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_cm_certificate.%s", [cert_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'auto_renew_enabled' should be present and set to 'true'", + "keyActualValue": "'auto_renew_enabled' is missing and defaults to 'false'", + } +} + +# REGLA 2: El atributo 'auto_renew_enabled' está explícitamente configurado como 'false'. +CxPolicy[result] { + doc := input.document[i] + certificate := doc.resource.ibm_cm_certificate[cert_name] + + certificate.auto_renew_enabled == false + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_cm_certificate.%s.auto_renew_enabled", [cert_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'auto_renew_enabled' attribute should be 'true'", + "keyActualValue": "'auto_renew_enabled' attribute is 'false'", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/negative1.tf b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/negative1.tf new file mode 100644 index 00000000000..e44ea543251 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/negative1.tf @@ -0,0 +1,8 @@ +resource "ibm_cm_certificate" "cert_compliant" { + instance_id = "crn:v1:bluemix:public:cloudcerts:..." + name = "cert-compliant" + label = "secure" + + # CORRECTO + auto_renew_enabled = true +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive1.tf b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive1.tf new file mode 100644 index 00000000000..0c8ea62b35c --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive1.tf @@ -0,0 +1,6 @@ +resource "ibm_cm_certificate" "cert_missing_attr" { + instance_id = "crn:v1:bluemix:public:cloudcerts:..." + name = "cert-missing" + label = "test" + # FALLO: Falta auto_renew_enabled +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive2.tf b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive2.tf new file mode 100644 index 00000000000..569d61fc484 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive2.tf @@ -0,0 +1,8 @@ +resource "ibm_cm_certificate" "cert_disabled" { + instance_id = "crn:v1:bluemix:public:cloudcerts:..." + name = "cert-disabled" + label = "test" + + # FALLO: Deshabilitado explícitamente + auto_renew_enabled = false +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..4680efed476 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Certificate Manager Auto Renew Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Certificate Manager Auto Renew Disabled", + "severity": "MEDIUM", + "line": 7, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/README.md b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/README.md new file mode 100644 index 00000000000..0aca177091f --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/README.md @@ -0,0 +1,77 @@ +# Regla KICS: IBM CIS DNS Record Not Proxied (Manual) + +## Descripción General + +Esta regla informativa (INFO) audita los registros DNS creados en **IBM Cloud Internet Services (CIS)** mediante el recurso `ibm_cis_dns_record`. + +En la arquitectura de CIS, la **Protección DDoS** de capa 3/4 y capa 7, el WAF y la aceleración CDN solo se activan cuando el tráfico es enrutado a través de la red perimetral de CIS. Esto se configura estableciendo el atributo `proxied` en `true` (modo comúnmente conocido como "Orange Cloud"). + +Si `proxied` es `false` (o se omite), CIS actúa solo como un servidor DNS tradicional ("DNS Only" o "Grey Cloud"), resolviendo la IP del servidor de origen directamente hacia el cliente. Esto expone la IP real del servidor a internet, haciéndolo vulnerable a ataques directos de denegación de servicio (DDoS) y eludiendo cualquier regla de seguridad perimetral de CIS. + +## Lógica de la Regla + +1. Identifica recursos de tipo `ibm_cis_dns_record`. +2. Verifica el valor del atributo `proxied`. +3. Si el valor es explícitamente `false` o si el atributo no ha sido definido (lo que resulta en un valor por defecto de `false`), genera una alerta informativa. + +**Nota para el Auditor:** No todos los registros deben estar protegidos por proxy. Registros TXT, MX, o servicios que utilizan protocolos no soportados por el proxy de CIS (como el tráfico no HTTP en ciertos puertos) deben permanecer en `false`. La alerta sirve para verificar manualmente que los registros `A`, `AAAA` y `CNAME` de aplicaciones web críticas estén bajo el escudo de protección. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Proxy Desactivado Explícitamente + +* **Descripción:** Se ha configurado `proxied = false`. El tráfico fluye directamente al servidor de origen sin pasar por los filtros de CIS. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_cis_dns_record" "dns_only" { + cis_id = ibm_cis.instance.id + domain_id = ibm_cis_domain.example.id + name = "web" + type = "A" + content = "1.2.3.4" + proxied = false # <-- Alerta INFO + } + ``` +* **Ubicación de la Alerta:** Atributo `proxied`. + +--- + +### Caso 2: Proxy No Definido (DNS Only por Defecto) + +* **Descripción:** Falta el atributo en la definición. Por defecto, CIS no activa el proxy, dejando el registro sin protección DDoS. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_cis_dns_record" "default_record" { + cis_id = ibm_cis.instance.id + domain_id = ibm_cis_domain.example.id + name = "app" + type = "A" + content = "1.2.3.4" + # Falta el atributo 'proxied' + } + ``` +* **Ubicación de la Alerta:** Bloque del recurso `ibm_cis_dns_record`. + +## Recurso Involucrado + +* `ibm_cis_dns_record` + +## Solución + +Habilita el proxy para activar la protección DDoS y las características de aceleración de CIS. + +```terraform +resource "ibm_cis_dns_record" "secure_record" { + cis_id = var.cis_instance_id + domain_id = var.domain_id + name = "www" + type = "A" + content = "1.2.3.4" + + # Habilitar protección DDoS, WAF y CDN + proxied = true +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/metadata.json b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/metadata.json new file mode 100644 index 00000000000..9227b92c430 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "124e18ee-0b42-474d-8623-185f108fa545", + "queryName": "IBM CIS DNS Record Not Proxied (Manual)", + "severity": "INFO", + "category": "Availability", + "descriptionText": "The DNS record in IBM Cloud Internet Services (CIS) is not proxied. DDoS protection, WAF, and CDN features are only active when 'proxied' is set to 'true'. Verify if this record points to a web workload that requires DDoS mitigation.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/cis_dns_record", + "platform": "Terraform", + "descriptionID": "124e18ee", + "cloudProvider": "ibm", + "cwe": "CWE-770", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/query.rego b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/query.rego new file mode 100644 index 00000000000..86d3a509490 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/query.rego @@ -0,0 +1,33 @@ +package Cx + +# CASO 1: El atributo 'proxied' está explícitamente en false. +CxPolicy[result] { + doc := input.document[i] + record := doc.resource.ibm_cis_dns_record[name] + + record.proxied == false + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_cis_dns_record.%s.proxied", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'proxied' should be set to 'true' to enable DDoS protection", + "keyActualValue": "'proxied' is set to 'false'", + } +} + +# CASO 2: El atributo 'proxied' falta (por defecto es false). +CxPolicy[result] { + doc := input.document[i] + record := doc.resource.ibm_cis_dns_record[name] + + object.get(record, "proxied", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_cis_dns_record.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'proxied' should be defined and set to 'true' to enable DDoS protection", + "keyActualValue": "'proxied' is missing (DNS resolution only, no DDoS protection)", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/negative1.tf new file mode 100644 index 00000000000..25f0badd996 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/negative1.tf @@ -0,0 +1,10 @@ +resource "ibm_cis_dns_record" "dns_record_secure" { + cis_id = "crn:v1:bluemix:public:internet-svcs:..." + domain_id = "example-id" + name = "www" + type = "A" + content = "1.2.3.4" + + # CORRECTO: Bajo el escudo de CIS + proxied = true +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive1.tf new file mode 100644 index 00000000000..8509014995b --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive1.tf @@ -0,0 +1,10 @@ +resource "ibm_cis_dns_record" "dns_record_false" { + cis_id = "crn:v1:bluemix:public:internet-svcs:..." + domain_id = "example-id" + name = "test" + type = "A" + content = "192.168.1.1" + + # FALLO: Deshabilitado explícitamente + proxied = false +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive2.tf b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive2.tf new file mode 100644 index 00000000000..de686df1b4c --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive2.tf @@ -0,0 +1,8 @@ +resource "ibm_cis_dns_record" "dns_record_missing" { + cis_id = "crn:v1:bluemix:public:internet-svcs:..." + domain_id = "example-id" + name = "test-missing" + type = "A" + content = "192.168.1.2" + # FALLO: Falta el atributo proxied +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..12c19487774 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "IBM CIS DNS Record Not Proxied (Manual)", + "severity": "INFO", + "line": 9, + "fileName": "positive1.tf" + }, + { + "queryName": "IBM CIS DNS Record Not Proxied (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/README.md b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/README.md new file mode 100644 index 00000000000..fd9eb45b2fc --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/README.md @@ -0,0 +1,72 @@ +# Regla KICS: IBM CIS WAF Not Enabled (Manual) + +## Descripción General + +Esta regla informativa (INFO) audita la configuración de **IBM Cloud Internet Services (CIS)** para asegurar que la protección de capa de aplicación esté activa. + +El recurso `ibm_cis_domain_settings` permite gestionar las capacidades de seguridad a nivel de dominio. El atributo `waf` funciona como el interruptor principal del Cortafuegos de Aplicaciones Web. Para mitigar riesgos asociados a vulnerabilidades web comunes y cumplir con estándares de seguridad industrial (como PCI-DSS), este atributo debe estar establecido explícitamente en `on`. + +**Nota importante:** Activar `waf = "on"` habilita el motor de inspección, pero la efectividad real depende de la configuración posterior de los paquetes de reglas (OWASP, reglas específicas de CIS, etc.) mediante el recurso `ibm_cis_waf_package`. Esta alerta sirve como punto de partida para verificar que la base de la protección está presente. + +## Lógica de la Regla + +1. Identifica todos los recursos de tipo `ibm_cis_domain_settings`. +2. Verifica la presencia y el valor del atributo `waf`. +3. Genera una alerta informativa si: + * El atributo `waf` está configurado con un valor distinto a `"on"` (por ejemplo, `"off"`). + * El atributo `waf` no ha sido definido en el recurso. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: WAF Deshabilitado Explícitamente + +* **Descripción:** El recurso define el WAF como `"off"`, desactivando la inspección de tráfico de capa 7. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_cis_domain_settings" "insecure" { + cis_id = ibm_cis.instance.id + domain_id = ibm_cis_domain.example.id + waf = "off" # <-- Alerta INFO + } + ``` +* **Ubicación de la Alerta:** Atributo `waf`. + +--- + +### Caso 2: Configuración de WAF Ausente + +* **Descripción:** No se especifica el estado del WAF, lo que puede llevar a estados de seguridad inconsistentes dependiendo del plan de CIS contratado. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_cis_domain_settings" "default_settings" { + cis_id = ibm_cis.instance.id + domain_id = ibm_cis_domain.example.id + # El atributo 'waf' no está definido + } + ``` +* **Ubicación de la Alerta:** Bloque del recurso `ibm_cis_domain_settings`. + +## Recurso Involucrado + +* `ibm_cis_domain_settings` + +## Solución + +Habilita el motor del WAF estableciendo el atributo a `"on"` dentro de la configuración del dominio. + +```terraform +resource "ibm_cis_domain_settings" "secure_settings" { + cis_id = ibm_cis.instance.id + domain_id = ibm_cis_domain.example.id + + # Habilitar WAF Global + waf = "on" + + # Recomendaciones adicionales de seguridad + ssl = "strict" + min_tls_version = "1.2" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/metadata.json b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/metadata.json new file mode 100644 index 00000000000..dbcc6548aa0 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "1e0c94f5-6178-4601-b33e-a86d8aa20bd6", + "queryName": "IBM CIS WAF Not Enabled (Manual)", + "severity": "INFO", + "category": "Networking and Firewall", + "descriptionText": "The Web Application Firewall (WAF) is not explicitly set to 'on' in the IBM Cloud Internet Services (CIS) domain settings. WAF is a critical compensatory control for protecting web workloads. Manual verification is required to ensure WAF is enabled and rules are properly tuned.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/cis_domain_settings", + "platform": "Terraform", + "descriptionID": "1e0c94f5", + "cloudProvider": "ibm", + "cwe": "CWE-1021", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/query.rego b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/query.rego new file mode 100644 index 00000000000..4c986b46e3f --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/query.rego @@ -0,0 +1,34 @@ +package Cx + +# CASO 1: El atributo 'waf' existe pero tiene un valor incorrecto (ej. "off"). +CxPolicy[result] { + doc := input.document[i] + settings := doc.resource.ibm_cis_domain_settings[name] + + settings.waf + settings.waf != "on" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_cis_domain_settings.%s.waf", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'waf' attribute should be set to 'on'", + "keyActualValue": sprintf("'waf' attribute is set to '%s'", [settings.waf]), + } +} + +# CASO 2: El atributo 'waf' NO existe en el recurso (valor por defecto varía por plan, se requiere definición explícita). +CxPolicy[result] { + doc := input.document[i] + settings := doc.resource.ibm_cis_domain_settings[name] + + not settings.waf + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_cis_domain_settings.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'waf' attribute should be defined and set to 'on'", + "keyActualValue": "'waf' attribute is missing", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/negative1.tf new file mode 100644 index 00000000000..82413ddf80d --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/negative1.tf @@ -0,0 +1,7 @@ +resource "ibm_cis_domain_settings" "settings_secure" { + cis_id = "crn:v1:bluemix:public:internet-svcs:..." + domain_id = "example-id" + + # CORRECTO: WAF habilitado + waf = "on" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive1.tf new file mode 100644 index 00000000000..51146b79b6a --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive1.tf @@ -0,0 +1,7 @@ +resource "ibm_cis_domain_settings" "settings_off" { + cis_id = "crn:v1:bluemix:public:internet-svcs:..." + domain_id = "example-id" + + # FALLO: WAF desactivado + waf = "off" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive2.tf b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive2.tf new file mode 100644 index 00000000000..1f424d8f271 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive2.tf @@ -0,0 +1,6 @@ +resource "ibm_cis_domain_settings" "settings_missing" { + cis_id = "crn:v1:bluemix:public:internet-svcs:..." + domain_id = "example-id" + # FALLO: Falta el atributo waf + ssl = "full" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..0069e2c83b5 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "IBM CIS WAF Not Enabled (Manual)", + "severity": "INFO", + "line": 6, + "fileName": "positive1.tf" + }, + { + "queryName": "IBM CIS WAF Not Enabled (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/README.md b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/README.md new file mode 100644 index 00000000000..c15aa384c73 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/README.md @@ -0,0 +1,75 @@ +# Regla KICS: IBM Cloudant Encryption with CMK (Manual) + +## Descripción General + +Esta regla informativa (INFO) audita las instancias de **IBM Cloudant** desplegadas mediante el recurso genérico `ibm_resource_instance` para verificar el uso de claves gestionadas por el cliente. + +Cloudant cifra los datos en reposo por defecto utilizando claves gestionadas por IBM. Sin embargo, para cumplir con requisitos de gestión de claves avanzada como **CMK** (Customer Managed Key) o **BYOK** (Bring Your Own Key), se debe inyectar el CRN (Cloud Resource Name) de una clave raíz proveniente de Key Protect o Hyper Protect Crypto Services. + +En Terraform, esta configuración se realiza pasando el parámetro específico `key_protect_key` dentro del mapa de `parameters` del recurso. Si este mapa se omite o si la clave no está presente dentro de él, la instancia se provisionará con el cifrado estándar del proveedor. + +## Lógica de la Regla + +La política realiza las siguientes comprobaciones sobre recursos `ibm_resource_instance` donde el servicio es `"cloudantnosqldb"`: +1. **Ausencia de Parámetros:** Detecta si el bloque `parameters` no ha sido definido en absoluto. +2. **Parámetro Faltante:** Detecta si el bloque `parameters` existe pero no incluye la entrada `key_protect_key`. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Bloque de Parámetros Ausente + +* **Descripción:** No se define ninguna configuración adicional, por lo que se asume el cifrado por defecto de IBM. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_resource_instance" "cloudant_no_params" { + name = "my-nosql-db" + service = "cloudantnosqldb" + plan = "standard" + location = "us-south" + # Falta el bloque parameters + } + ``` +* **Ubicación de la Alerta:** Nivel del recurso `ibm_resource_instance`. + +--- + +### Caso 2: Clave de Cifrado Faltante en Parámetros + +* **Descripción:** Se definen parámetros pero se omite la clave de seguridad `key_protect_key`. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_resource_instance" "cloudant_partial_params" { + name = "my-nosql-db" + service = "cloudantnosqldb" + plan = "standard" + location = "us-south" + parameters = { + "db_type" = "nosql" + } + } + ``` +* **Ubicación de la Alerta:** Atributo `parameters`. + +## Recurso Involucrado + +* `ibm_resource_instance` (Service: `cloudantnosqldb`) + +## Solución + +Añade el bloque `parameters` con la clave `key_protect_key` apuntando a un CRN válido. + +```terraform +resource "ibm_resource_instance" "cloudant_secure" { + name = "my-secure-cloudant" + service = "cloudantnosqldb" + plan = "standard" + location = "us-south" + + parameters = { + key_protect_key = "crn:v1:bluemix:public:kms:us-south:a/aaaa:bbbb:key:cccc" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/metadata.json b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/metadata.json new file mode 100644 index 00000000000..2e63c668243 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "601ca2bb-20a9-4113-83b3-866a3d1a2a67", + "queryName": "IBM Cloudant Encryption with CMK (Manual)", + "severity": "INFO", + "category": "Encryption", + "descriptionText": "The IBM Cloudant instance (provisioned via 'ibm_resource_instance') does not appear to have Customer Managed Encryption configured. To enable CMK/BYOK, the 'parameters' block must contain the Key Protect root key CRN (usually 'key_protect_key'). Manual verification is required.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_instance", + "platform": "Terraform", + "descriptionID": "601ca2bb", + "cloudProvider": "ibm", + "cwe": "CWE-312", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/query.rego b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/query.rego new file mode 100644 index 00000000000..b4949dff8d0 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/query.rego @@ -0,0 +1,36 @@ +package Cx + +# CASO 1: El bloque 'parameters' está ausente. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.ibm_resource_instance[name] + resource.service == "cloudantnosqldb" + + object.get(resource, "parameters", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_resource_instance.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "Cloudant instance should have a 'parameters' block containing 'key_protect_key'", + "keyActualValue": "The 'parameters' block is missing (using default encryption)", + } +} + +# CASO 2: El bloque 'parameters' existe pero falta 'key_protect_key'. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.ibm_resource_instance[name] + resource.service == "cloudantnosqldb" + + resource.parameters + object.get(resource.parameters, "key_protect_key", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_resource_instance.%s.parameters", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "Cloudant 'parameters' should contain 'key_protect_key' with a valid Key Protect CRN", + "keyActualValue": "'key_protect_key' is missing within the parameters map", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/negative1.tf new file mode 100644 index 00000000000..6f7be642193 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/negative1.tf @@ -0,0 +1,10 @@ +resource "ibm_resource_instance" "cloudant_secure" { + name = "cloudant-secure" + service = "cloudantnosqldb" + plan = "standard" + location = "us-south" + + parameters = { + key_protect_key = "crn:v1:bluemix:public:kms:us-south:a/test:test:key:test" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive1.tf new file mode 100644 index 00000000000..31bb0b041db --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive1.tf @@ -0,0 +1,6 @@ +resource "ibm_resource_instance" "cloudant_no_params" { + name = "cloudant-no-params" + service = "cloudantnosqldb" + plan = "standard" + location = "us-south" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive2.tf b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive2.tf new file mode 100644 index 00000000000..48239b22f62 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive2.tf @@ -0,0 +1,10 @@ +resource "ibm_resource_instance" "cloudant_partial_params" { + name = "cloudant-partial" + service = "cloudantnosqldb" + plan = "standard" + location = "us-south" + + parameters = { + "db_type" = "nosql" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..7f0f616c691 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "IBM Cloudant Encryption with CMK (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "IBM Cloudant Encryption with CMK (Manual)", + "severity": "INFO", + "line": 7, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/README.md b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/README.md new file mode 100644 index 00000000000..a8aad50d427 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/README.md @@ -0,0 +1,62 @@ +# Regla KICS: IBM Cluster Entitlement Key Missing (Automated) + +## Descripción General + +Esta regla informativa (INFO) audita el recurso `ibm_container_cluster` en IBM Cloud Kubernetes Service (IKS). + +En IBM Cloud, la gestión de **Image Pull Secrets** (credenciales para descargar imágenes de contenedores) se puede automatizar en Terraform de varias formas. Una de las más directas y seguras para el software empresarial es el uso del argumento `entitlement`. + +Cuando se define este argumento, el sistema crea automáticamente un secreto de Kubernetes dentro del clúster con las credenciales necesarias para autenticarse contra el **IBM Entitled Registry**. Esto asegura la integridad de la cadena de suministro al permitir el despliegue de **IBM Cloud Paks** y otro software licenciado sin la necesidad de crear, inyectar o gestionar manualmente objetos `Secret` de Kubernetes, reduciendo el riesgo de exposición de credenciales y fallos en el despliegue por secretos expirados. + +## Lógica de la Regla + +1. Identifica recursos de tipo `ibm_container_cluster`. +2. Verifica si el atributo `entitlement` está presente en la configuración. +3. Si falta, genera una alerta informativa. + +**Nota técnica:** No todos los clústeres requieren software titulado (muchos corren aplicaciones propias). Sin embargo, en entornos corporativos de IBM, es una mejor práctica verificar si se ha habilitado esta automatización. Para registros privados que no sean el Entitled Registry, se recomienda usar el recurso `ibm_container_bind_service`. + +## Casos de Fallo Detectados + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso 1: Clave de Titulación (Entitlement) Faltante + +* **Descripción:** El clúster se provisiona sin credenciales automáticas para el registro de IBM. Esto requerirá que el administrador gestione los secretos de descarga de imágenes de forma manual. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_container_cluster" "example_no_entitlement" { + name = "my-app-cluster" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + public_vlan_id = "1234567" + private_vlan_id = "7654321" + + # Falta el atributo 'entitlement' + } + ``` +* **Ubicación de la Alerta:** Bloque del recurso `ibm_container_cluster`. + +## Recurso Involucrado + +* `ibm_container_cluster` + +## Solución + +Si el clúster va a ejecutar software licenciado de IBM, añade tu clave de titulación al recurso del clúster. + +```terraform +resource "ibm_container_cluster" "secure_cluster" { + name = "production-cluster" + datacenter = "dal10" + machine_type = "u3c.2x4" + hardware = "shared" + public_vlan_id = "123456" + private_vlan_id = "654321" + + # Automatización del Image Pull Secret para IBM Entitled Registry + entitlement = "cloud_pak_entitlement_key_or_api_key" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/metadata.json b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/metadata.json new file mode 100644 index 00000000000..36922ba0ea7 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "d2fc37af-3cd9-4830-b8a0-a3eda8fba0ed", + "queryName": "IBM Cluster Entitlement Key Missing (Automated)", + "severity": "INFO", + "category": "Supply-Chain", + "descriptionText": "The IBM Cloud Kubernetes Service cluster does not have an 'entitlement' key configured. This argument automates the creation of image pull secrets for the IBM Entitled Registry. If using IBM Cloud Paks or entitled software, this should be defined to ensure secure image pull access.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/container_cluster#entitlement", + "platform": "Terraform", + "descriptionID": "d2fc37af", + "cloudProvider": "ibm", + "cwe": "CWE-284", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/query.rego b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/query.rego new file mode 100644 index 00000000000..7e661363b45 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/query.rego @@ -0,0 +1,17 @@ +package Cx + +# REGLA: Verificar si el cluster tiene configurada la clave de "entitlement". +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.ibm_container_cluster[name] + + object.get(cluster, "entitlement", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_container_cluster.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'entitlement' attribute should be defined for clusters running IBM Entitled Software", + "keyActualValue": "'entitlement' attribute is missing", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/negative1.tf b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/negative1.tf new file mode 100644 index 00000000000..0d9ea9b13b7 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/negative1.tf @@ -0,0 +1,15 @@ +provider "ibm" { + region = "us-south" +} + +resource "ibm_container_cluster" "cluster_with_entitlement" { + name = "secure-cluster" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + public_vlan_id = "123" + private_vlan_id = "456" + + # CORRECTO: Se automatiza el secreto de descarga + entitlement = "my-entitlement-key-crn" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive1.tf b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive1.tf new file mode 100644 index 00000000000..cf80ba4a204 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive1.tf @@ -0,0 +1,13 @@ +provider "ibm" { + region = "us-south" +} + +resource "ibm_container_cluster" "cluster_without_entitlement" { + name = "test-cluster" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + public_vlan_id = "123" + private_vlan_id = "456" + # FALLO: No se define 'entitlement' +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive_expected_result.json new file mode 100644 index 00000000000..b2aa6c25605 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "IBM Cluster Entitlement Key Missing (Automated)", + "severity": "INFO", + "line": 5, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/README.md b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/README.md new file mode 100644 index 00000000000..4472f3e9caf --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/README.md @@ -0,0 +1,54 @@ +# Regla KICS: IBM Cluster Missing VA Alerts (Automated) + +## Descripción General + +Esta regla de severidad **MEDIA** audita el despliegue de clústeres de Kubernetes (`ibm_container_cluster`) en IBM Cloud para asegurar que existan canales de comunicación activos para la gestión de vulnerabilidades. + +El uso de orquestadores de contenedores implica el manejo constante de imágenes de software. IBM Cloud proporciona el **Vulnerability Advisor (VA)**, que escanea automáticamente estas imágenes en el registro. Sin embargo, en un flujo de trabajo de DevSecOps eficiente, el escaneo por sí solo no es suficiente; es imperativo que el sistema pueda notificar a los responsables cuando se detecten nuevas vulnerabilidades o cambios en el estado de seguridad de una imagen. + +Si estás desplegando un clúster mediante Terraform, la práctica recomendada es incluir en el mismo código la configuración de las notificaciones (`ibm_container_va_notification`), ya sea mediante correo electrónico o webhooks, para garantizar una respuesta rápida ante posibles amenazas. + +## Lógica de la Regla + +1. Identifica todos los recursos de tipo `ibm_container_cluster` en la configuración. +2. Escanea el documento de Terraform en busca de *cualquier* instancia del recurso `ibm_container_va_notification`. +3. Si se detecta la creación de un clúster pero no existe ninguna configuración de notificaciones de VA, genera una alerta apuntando al recurso del clúster. + +## Casos de Fallo Detectados + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso 1: Clúster sin Alertas de Vulnerabilidad + +* **Descripción:** Se define un clúster de Kubernetes en la infraestructura, pero se omite la configuración del canal de alertas (email/webhook) para el Vulnerability Advisor. Esto crea un punto ciego donde las imágenes vulnerables podrían pasar desapercibidas. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_container_cluster" "production_cluster" { + name = "prod-cluster" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + public_vlan_id = "123456" + private_vlan_id = "654321" + + # No hay un recurso 'ibm_container_va_notification' asociado en el proyecto + } + ``` +* **Ubicación de la Alerta:** Bloque del recurso `ibm_container_cluster`. + +## Recurso Involucrado + +* `ibm_container_cluster` +* `ibm_container_va_notification` + +## Solución + +Para solucionar esta alerta, añade un recurso de notificación de VA que apunte al clúster o al grupo de recursos correspondiente. + +```terraform +resource "ibm_container_va_notification" "vulnerability_alerts" { + cluster_id = ibm_container_cluster.production_cluster.id + email = "security-ops@tu-empresa.com" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json new file mode 100644 index 00000000000..6d1b5a772d7 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "92440d0d-889c-49c5-a0e6-13c5f326b872", + "queryName": "IBM Container Registry VA Alerts Missing (Automated)", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that notifications are enabled for the Vulnerability Advisor (VA) in IBM Cloud Container Registry. The resource 'ibm_container_va_notification' allows configuring alerts (email, webhook) for new vulnerabilities found in container images.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/container_va_notification", + "platform": "Terraform", + "descriptionID": "92440d0d", + "cloudProvider": "ibm", + "cwe": "CWE-778", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/query.rego b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/query.rego new file mode 100644 index 00000000000..6137eaab409 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/query.rego @@ -0,0 +1,19 @@ +package Cx + +# REGLA: Verificar si el cluster de Kubernetes tiene configuradas las alertas de vulnerabilidad. +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.ibm_container_cluster[name] + + va_notifications := [n | n := input.document[_].resource.ibm_container_va_notification[_]] + + count(va_notifications) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_container_cluster.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "A 'ibm_container_va_notification' resource should be defined to alert on image vulnerabilities", + "keyActualValue": "Vulnerability Advisor notifications are missing for this cluster environment", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/negative1.tf b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/negative1.tf new file mode 100644 index 00000000000..dc8b4fbc202 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/negative1.tf @@ -0,0 +1,18 @@ +provider "ibm" { + region = "us-south" +} + +resource "ibm_container_cluster" "secure_cluster" { + name = "secure-setup" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + public_vlan_id = "123" + private_vlan_id = "456" +} + +# CORRECTO: Se define la notificación para el VA +resource "ibm_container_va_notification" "alerts" { + cluster_id = ibm_container_cluster.secure_cluster.id + email = "admin@example.com" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive1.tf b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive1.tf new file mode 100644 index 00000000000..5c53735bfa1 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive1.tf @@ -0,0 +1,13 @@ +provider "ibm" { + region = "us-south" +} + +resource "ibm_container_cluster" "cluster_without_va" { + name = "vulnerable-setup" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + public_vlan_id = "123" + private_vlan_id = "456" + # FALLO: No existe un ibm_container_va_notification en el documento +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..f6feb25008e --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "IBM Container Registry VA Alerts Missing (Automated)", + "severity": "MEDIUM", + "line": 5, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/README.md b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/README.md new file mode 100644 index 00000000000..1635ba2a4fd --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/README.md @@ -0,0 +1,60 @@ +# Regla KICS: IBM COS Bucket Encryption (CMK/BYOK/KYOK) Manual + +## Descripción General + +Esta regla unificada (INFO) verifica si los buckets de **IBM Cloud Object Storage (COS)** están configurados para utilizar claves de cifrado gestionadas por el cliente, en lugar de las claves estándar gestionadas por el proveedor. + +En la arquitectura de IBM Cloud, el uso del argumento `key_protect` en el recurso de Terraform es el habilitador técnico para implementar tres niveles avanzados de seguridad: + +1. **CMK (Customer Managed Key):** Utiliza claves raíz almacenadas en el servicio **Key Protect**. +2. **BYOK (Bring Your Own Key):** Permite al cliente importar su propio material de clave generado externamente. +3. **KYOK (Keep Your Own Key):** Ofrece el nivel más alto de aislamiento mediante el uso de **Hyper Protect Crypto Services (HPCS)** con un HSM dedicado con certificación FIPS 140-2 Nivel 4. + +Si este argumento se omite, el bucket utiliza el cifrado en reposo por defecto de IBM (AES-256), donde IBM controla la rotación y el ciclo de vida de la clave. Esta regla sirve para que el auditor verifique si la sensibilidad de los datos almacenados exige un control soberano de las llaves. + +## Lógica de la Regla + +1. Identifica todos los recursos de tipo `ibm_cos_bucket`. +2. Verifica si el atributo `key_protect` está presente en la definición del bucket. +3. Genera una alerta informativa si el atributo no existe, indicando que se está utilizando la configuración de cifrado por defecto. + +## Casos de Fallo Detectados + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso 1: Cifrado Gestionado por el Proveedor (Default) + +* **Descripción:** El bucket de COS ha sido configurado sin especificar una clave de seguridad del cliente. IBM Cloud cifra los datos, pero el cliente no posee el control total sobre la clave raíz. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_cos_bucket" "public_data" { + bucket_name = "my-bucket-standard" + resource_instance_id = ibm_resource_instance.cos_instance.id + storage_class = "smart" + region_location = "us-south" + + # Falta el atributo 'key_protect' + } + ``` +* **Ubicación de la Alerta:** Bloque del recurso `ibm_cos_bucket`. + +## Recurso Involucrado + +* `ibm_cos_bucket` + +## Solución + +Para habilitar CMK, BYOK o KYOK, debes proporcionar el CRN (Cloud Resource Name) de tu clave raíz de Key Protect o Hyper Protect en el atributo `key_protect`. + +```terraform +resource "ibm_cos_bucket" "secure_storage" { + bucket_name = "vault-bucket-secure" + resource_instance_id = ibm_resource_instance.cos_instance.id + storage_class = "smart" + region_location = "us-south" + + # Habilitar Cifrado Gestionado por el Cliente + key_protect = "crn:v1:bluemix:public:kms:us-south:a/aaaa:bbbb:key:cccc" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json new file mode 100644 index 00000000000..663d9c51106 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "8f65bf01-e9e9-4dd6-82b1-67051c2f073d", + "queryName": "IBM COS Bucket Encryption (CMK/BYOK/KYOK) Manual", + "severity": "INFO", + "category": "Encryption", + "descriptionText": "The Cloud Object Storage bucket relies on default provider-managed encryption. It is not configured with 'key_protect', which is required for Customer Managed Keys (CMK), Bring Your Own Key (BYOK), or Keep Your Own Key (KYOK). Manual verification is required to determine the specific encryption requirement.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/cos_bucket", + "platform": "Terraform", + "descriptionID": "8f65bf01", + "cloudProvider": "ibm", + "cwe": "CWE-312", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/query.rego b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/query.rego new file mode 100644 index 00000000000..04a56602fc0 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/query.rego @@ -0,0 +1,17 @@ +package Cx + +# REGLA UNIFICADA: Verificación de Cifrado Gestionado por el Cliente en COS. +CxPolicy[result] { + doc := input.document[i] + bucket := doc.resource.ibm_cos_bucket[name] + + object.get(bucket, "key_protect", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_cos_bucket.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'key_protect' attribute should be defined (required for CMK, BYOK, or KYOK)", + "keyActualValue": "'key_protect' is missing (using default provider-managed encryption)", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/negative1.tf b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/negative1.tf new file mode 100644 index 00000000000..a096fdcc81f --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/negative1.tf @@ -0,0 +1,13 @@ +provider "ibm" { + region = "us-south" +} + +resource "ibm_cos_bucket" "bucket_secure" { + bucket_name = "secure-bucket" + resource_instance_id = "crn:v1:bluemix:public:cloud-object-storage:..." + storage_class = "standard" + region_location = "us-south" + + # CORRECTO: Se define la clave de cifrado del cliente + key_protect = "crn:v1:bluemix:public:kms:us-south:a/test:test:key:test" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive1.tf b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive1.tf new file mode 100644 index 00000000000..c71b8b828c4 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive1.tf @@ -0,0 +1,11 @@ +provider "ibm" { + region = "us-south" +} + +resource "ibm_cos_bucket" "bucket_insecure" { + bucket_name = "insecure-bucket" + resource_instance_id = "crn:v1:bluemix:public:cloud-object-storage:..." + storage_class = "standard" + region_location = "us-south" + # FALLO: Falta el atributo key_protect +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive_expected_result.json new file mode 100644 index 00000000000..1a8da52305e --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "IBM COS Bucket Encryption (CMK/BYOK/KYOK) Manual", + "severity": "INFO", + "line": 5, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/README.md b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/README.md new file mode 100644 index 00000000000..d2ed09aeeff --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/README.md @@ -0,0 +1,57 @@ +# Regla KICS: IBM Cloud Database Without CMK (Manual) + +## Descripción General + +Esta regla informativa (INFO) audita los recursos `ibm_database` en Terraform para identificar instancias de la familia **IBM Cloud Databases (ICD)** que no utilizan claves de cifrado gestionadas por el cliente. + +Este recurso se utiliza para aprovisionar una amplia variedad de servicios de datos gestionados, incluyendo PostgreSQL, Redis, Elasticsearch, MongoDB, etcd, entre otros. Por defecto, todas estas bases de datos cifran el almacenamiento en reposo utilizando claves gestionadas automáticamente por IBM Cloud. + +Sin embargo, para cumplir con marcos regulatorios estrictos o políticas internas de seguridad avanzadas (**CMK**, **BYOK** o **KYOK**), es imperativo que el cliente proporcione y gestione la clave raíz. Esto se logra asignando el CRN (Cloud Resource Name) de una clave proveniente de **Key Protect** o **Hyper Protect Crypto Services (HPCS)** en el argumento `key_protect_key`. + +## Lógica de la Regla + +La política realiza las siguientes acciones: +1. Identifica todos los recursos de tipo `ibm_database` en el código de Terraform. +2. Verifica si el atributo `key_protect_key` ha sido definido. +3. Si el atributo falta, genera una alerta informativa indicando que la instancia depende del cifrado por defecto del proveedor. + +## Casos de Fallo Detectados + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso 1: Cifrado por Defecto (Provider-Managed) + +* **Descripción:** La base de datos ICD ha sido configurada sin asignar una clave de seguridad propia. Aunque los datos están cifrados, el cliente no tiene control sobre el ciclo de vida de la clave de cifrado de volumen. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_database" "postgres_default" { + name = "my-db-standard" + service = "databases-for-postgresql" + plan = "standard" + location = "us-south" + + # Falta el atributo 'key_protect_key' + } + ``` +* **Ubicación de la Alerta:** Bloque del recurso `ibm_database`. + +## Recurso Involucrado + +* `ibm_database` + +## Solución + +Para habilitar el cifrado gestionado por el cliente, asigna el CRN de una clave raíz válida de tu Vault (Key Protect o HPCS) al argumento `key_protect_key`. + +```terraform +resource "ibm_database" "secure_db" { + name = "my-secure-postgres" + service = "databases-for-postgresql" + plan = "standard" + location = "us-south" + + # Habilitar CMK/BYOK/KYOK + key_protect_key = "crn:v1:bluemix:public:kms:us-south:a/aaaa:bbbb:key:cccc" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/metadata.json b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/metadata.json new file mode 100644 index 00000000000..78ee536c83a --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "c973475c-4797-42b1-8cee-4038c050283e", + "queryName": "IBM Cloud Database Without CMK (Manual)", + "severity": "INFO", + "category": "Encryption", + "descriptionText": "The IBM Cloud Database instance is not configured with a Customer Managed Key (CMK). It relies on default provider-managed encryption. Verify if the data sensitivity requires Bring Your Own Key (BYOK) or Keep Your Own Key (KYOK) via the 'key_protect_key' argument.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/database", + "platform": "Terraform", + "descriptionID": "c973475c", + "cloudProvider": "ibm", + "cwe": "CWE-312", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/query.rego b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/query.rego new file mode 100644 index 00000000000..7b0a644b906 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/query.rego @@ -0,0 +1,17 @@ +package Cx + +# CASO 1: Base de datos sin 'key_protect_key'. +CxPolicy[result] { + doc := input.document[i] + db := doc.resource.ibm_database[name] + + object.get(db, "key_protect_key", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_database.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'key_protect_key' attribute should be defined with a Key Protect/HPCS CRN", + "keyActualValue": "'key_protect_key' is missing (using default provider-managed encryption)", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/negative1.tf new file mode 100644 index 00000000000..e180275711d --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/negative1.tf @@ -0,0 +1,13 @@ +provider "ibm" { + region = "us-south" +} + +resource "ibm_database" "db_secure" { + name = "db-protected" + service = "databases-for-postgresql" + plan = "standard" + location = "us-south" + + # CORRECTO: Se define la clave de cifrado del cliente + key_protect_key = "crn:v1:bluemix:public:kms:us-south:a/test:test:key:test" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive1.tf new file mode 100644 index 00000000000..0263c170bcf --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive1.tf @@ -0,0 +1,11 @@ +provider "ibm" { + region = "us-south" +} + +resource "ibm_database" "db_insecure" { + name = "db-standard" + service = "databases-for-mongodb" + plan = "standard" + location = "us-south" + # FALLO: Falta el atributo key_protect_key +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..9385193bf19 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "IBM Cloud Database Without CMK (Manual)", + "severity": "INFO", + "line": 5, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/README.md b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/README.md new file mode 100644 index 00000000000..2aa835fe523 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/README.md @@ -0,0 +1,69 @@ +# Regla KICS: IBM Account IP Restrictions (Manual) + +## Descripción General + +Esta regla informativa (INFO) audita la configuración global de la cuenta en IBM Cloud a través del recurso `ibm_iam_account_settings`. + +Para mitigar el riesgo de compromiso de credenciales y accesos no autorizados, es una práctica de seguridad fundamental restringir el acceso a la consola de IBM Cloud y a las interfaces de API únicamente a direcciones IP o rangos de red de confianza (como la VPN corporativa, oficinas centrales o gateways de seguridad). + +Si el atributo `allowed_ip_addresses` no se configura, IBM Cloud permite por defecto el acceso desde cualquier dirección IP pública (0.0.0.0/0). Habilitar estas restricciones reduce drásticamente la superficie de ataque para amenazas externas, ya que incluso si un atacante obtiene credenciales válidas, el sistema denegará la conexión si no se origina desde un origen autorizado. + +## Lógica de la Regla + +La política realiza las siguientes validaciones: +1. Identifica el recurso único `ibm_iam_account_settings` en el proyecto. +2. **Validación de Presencia:** Verifica si el atributo `allowed_ip_addresses` ha sido definido. +3. **Validación de Integridad:** Verifica que la lista proporcionada no sea una lista vacía `[]`. +4. Genera una alerta informativa si falta la configuración, instando al auditor a definir el perímetro de red de la cuenta. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Acceso Irrestricto (Sin Atributo) + +* **Descripción:** El recurso no define ninguna restricción de red. El acceso a la cuenta está abierto a cualquier punto de internet. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_iam_account_settings" "default" { + mfa = "TOTP" + session_expiration_in_seconds = 3600 + # Falta el atributo 'allowed_ip_addresses' + } + ``` +* **Ubicación de la Alerta:** Bloque del recurso `ibm_iam_account_settings`. + +--- + +### Caso 2: Lista de IPs Vacía + +* **Descripción:** Se define el atributo pero no se incluyen direcciones IP de confianza. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_iam_account_settings" "empty_list" { + allowed_ip_addresses = [] # <-- Alerta INFO + } + ``` +* **Ubicación de la Alerta:** Atributo `allowed_ip_addresses`. + +## Recurso Involucrado + +* `ibm_iam_account_settings` + +## Solución + +Define explícitamente la lista de direcciones IP o subredes (en formato CIDR) que deben tener permiso de acceso a la cuenta. + +```terraform +resource "ibm_iam_account_settings" "secure_account" { + mfa = "TOTP" + session_expiration_in_seconds = 86400 + + # Restringir acceso solo a la VPN corporativa y oficina central + allowed_ip_addresses = [ + "203.0.113.10", # IP Estática Oficina + "192.0.2.0/24" # Rango VPN Corporativa + ] +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/metadata.json new file mode 100644 index 00000000000..c220420064a --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "61d76d70-0021-45c7-855d-c8c5c3116877", + "queryName": "IBM Account IP Restrictions (Manual)", + "severity": "INFO", + "category": "Networking and Firewall", + "descriptionText": "The account global settings do not enforce IP address restrictions. The 'allowed_ip_addresses' attribute should be configured to restrict login access (including the account owner) to trusted networks only.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_account_settings", + "platform": "Terraform", + "descriptionID": "61d76d70", + "cloudProvider": "ibm", + "cwe": "CWE-284", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/query.rego b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/query.rego new file mode 100644 index 00000000000..7be385c5a10 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/query.rego @@ -0,0 +1,34 @@ +package Cx + +# CASO 1: Restricciones de IP no configuradas (Atributo ausente). +CxPolicy[result] { + doc := input.document[i] + settings := doc.resource.ibm_iam_account_settings[name] + + object.get(settings, "allowed_ip_addresses", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_iam_account_settings.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'allowed_ip_addresses' should be defined with a list of trusted IPs", + "keyActualValue": "'allowed_ip_addresses' is missing (access allowed from anywhere)", + } +} + +# CASO 2: Restricciones definidas pero lista vacía. +CxPolicy[result] { + doc := input.document[i] + settings := doc.resource.ibm_iam_account_settings[name] + + ips := settings.allowed_ip_addresses + count(ips) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_iam_account_settings.%s.allowed_ip_addresses", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'allowed_ip_addresses' should contain at least one trusted IP/Subnet", + "keyActualValue": "'allowed_ip_addresses' is empty", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/negative1.tf new file mode 100644 index 00000000000..96939b1d2a8 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/negative1.tf @@ -0,0 +1,7 @@ +resource "ibm_iam_account_settings" "settings_secure" { + mfa = "TOTP" + allowed_ip_addresses = [ + "10.1.2.3", + "192.168.1.0/24" + ] +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive1.tf new file mode 100644 index 00000000000..253da211578 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive1.tf @@ -0,0 +1,4 @@ +resource "ibm_iam_account_settings" "settings_no_ips" { + mfa = "TOTP" + session_expiration_in_seconds = 3600 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive2.tf b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive2.tf new file mode 100644 index 00000000000..f3bbafbe44e --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive2.tf @@ -0,0 +1,3 @@ +resource "ibm_iam_account_settings" "settings_empty_ips" { + allowed_ip_addresses = [] +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..5f64891c33a --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "IBM Account IP Restrictions (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "IBM Account IP Restrictions (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/README.md b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/README.md new file mode 100644 index 00000000000..0531e8afc6f --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/README.md @@ -0,0 +1,46 @@ +# Regla KICS: MFA Obligatorio a Nivel de Cuenta en IBM IAM + +## Descripción General + +Esta regla de KICS para Terraform asegura que la Autenticación Multi-Factor (MFA) esté habilitada y forzada a un nivel seguro para toda la cuenta de IBM Cloud. La configuración se gestiona a través del recurso `ibm_iam_account_settings`. + +Forzar el uso de MFA es una de las medidas de seguridad más efectivas para proteger una cuenta contra el acceso no autorizado. Incluso si las credenciales (usuario y contraseña) de un administrador o usuario con privilegios son comprometidas, el MFA actúa como una barrera crítica de segundo nivel. + +## Lógica de la Regla + +La política se divide en tres comprobaciones complementarias para cubrir todos los escenarios de riesgo: +1. **Ausencia de Recurso:** Verifica que exista el recurso de configuración de cuenta. +2. **Atributo Faltante:** Verifica que el parámetro `mfa` esté definido explícitamente. +3. **Nivel Inseguro:** Asegura que no se utilicen niveles débiles. Los niveles seguros aceptados son `LEVEL2` (TOTP/App de autenticación) y `LEVEL3` (U2F/Llave física). + +## Casos de Fallo Detectados + +A continuación se describen los tres escenarios que esta política detectará. + +--- + +### Caso 1: Recurso `ibm_iam_account_settings` Ausente +* **Descripción:** No se está gestionando la política de la cuenta mediante código, dejando el MFA bajo configuración manual o por defecto (inseguro). +* **Ubicación:** Bloque `provider "ibm"`. + +### Caso 2: Atributo `mfa` Ausente +* **Descripción:** El recurso de configuración existe pero no define el comportamiento del MFA. +* **Ubicación:** Recurso `ibm_iam_account_settings`. + +### Caso 3: Valor de `mfa` Inseguro (`NONE` o `LEVEL1`) +* **Descripción:** El MFA está desactivado (`NONE`) o utiliza métodos débiles como email (`LEVEL1`). +* **Ubicación:** Atributo `mfa`. + +## Recurso Involucrado + +* `ibm_iam_account_settings` + +## Solución + +Para cumplir con esta política, define el recurso de configuración de cuenta y fuerza el uso de MFA de nivel 2 o superior. + +```terraform +resource "ibm_iam_account_settings" "secure_iam_policy" { + # Forzar el uso de TOTP (Time-based One-Time Password) + mfa = "LEVEL2" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json new file mode 100644 index 00000000000..5cbe9b1f843 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "ebaef99e-4add-440e-8270-caeb718e7c93", + "queryName": "Account Level MFA Is Not Enforced", + "severity": "HIGH", + "category": "Access Control", + "descriptionText": "Enforces Multi-Factor Authentication (MFA) at the account level. Requiring MFA is a fundamental security practice to prevent unauthorized access resulting from compromised credentials.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_account_settings#mfa", + "platform": "Terraform", + "descriptionID": "ebaef99e", + "cloudProvider": "ibm", + "cwe": "CWE-308", + "riskScore": 9.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego new file mode 100644 index 00000000000..a2a2e9ebd82 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego @@ -0,0 +1,50 @@ +package Cx + +# REGLA 1: El recurso 'ibm_iam_account_settings' no existe en la configuración. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.ibm + + all_iam_settings := [settings | + settings := input.document[_].resource.ibm_iam_account_settings[_] + ] + + count(all_iam_settings) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.ibm", + "issueType": "MissingAttribute", + "keyExpectedValue": "Resource 'ibm_iam_account_settings' should exist to enforce MFA", + "keyActualValue": "Resource 'ibm_iam_account_settings' is missing in this IBM configuration", + } +} + +# REGLA 2: El atributo 'mfa' está ausente dentro del recurso. +CxPolicy[result] { + settings := input.document[i].resource.ibm_iam_account_settings[settings_name] + object.get(settings, "mfa", null) == null + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_iam_account_settings.%s", [settings_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'mfa' attribute should be present and set to 'LEVEL2' or 'LEVEL3'", + "keyActualValue": "'mfa' attribute is missing", + } +} + +# REGLA 3: El atributo 'mfa' tiene un valor inseguro ('NONE' o 'LEVEL1'). +CxPolicy[result] { + settings := input.document[i].resource.ibm_iam_account_settings[settings_name] + insecure_mfa_levels := {"NONE", "LEVEL1"} + insecure_mfa_levels[settings.mfa] + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_iam_account_settings.%s.mfa", [settings_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'mfa' attribute should be 'LEVEL2' or 'LEVEL3'", + "keyActualValue": sprintf("'mfa' attribute is set to '%s'", [settings.mfa]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/negative1.tf b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/negative1.tf new file mode 100644 index 00000000000..0ca8fbb6935 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/negative1.tf @@ -0,0 +1,4 @@ +resource "ibm_iam_account_settings" "iam_secure" { + # CORRECTO: LEVEL2 es seguro + mfa = "LEVEL2" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive1.tf b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive1.tf new file mode 100644 index 00000000000..34c0e3bb7e1 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive1.tf @@ -0,0 +1,8 @@ +provider "ibm" { + region = "us-south" +} + +# Solo recursos de infraestructura, nada de IAM settings +resource "ibm_is_vpc" "example" { + name = "test-vpc" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive2.tf b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive2.tf new file mode 100644 index 00000000000..2435762e151 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive2.tf @@ -0,0 +1,4 @@ +resource "ibm_iam_account_settings" "iam_no_mfa" { + # Falta el atributo mfa + session_expiration_in_seconds = 3600 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive3.tf b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive3.tf new file mode 100644 index 00000000000..8c8a160cf24 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive3.tf @@ -0,0 +1,4 @@ +resource "ibm_iam_account_settings" "iam_weak_mfa" { + # FALLO: LEVEL1 no es suficientemente seguro + mfa = "LEVEL1" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..6f93077e52d --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Account Level MFA Is Not Enforced", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Account Level MFA Is Not Enforced", + "severity": "HIGH", + "line": 1, + "fileName": "positive2.tf" + }, + { + "queryName": "Account Level MFA Is Not Enforced", + "severity": "HIGH", + "line": 3, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/README.md b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/README.md new file mode 100644 index 00000000000..77a3fa2022b --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/README.md @@ -0,0 +1,60 @@ +# Regla KICS: IBM Cloud API Keys Unused for 180 Days (Manual) + +## Descripción General + +Esta regla informativa (INFO) audita la creación de claves de API en **IBM Cloud**, cubriendo tanto las claves asociadas a usuarios (`ibm_iam_api_key`) como las asociadas a identidades de servicio o Service IDs (`ibm_iam_service_api_key`). + +El cumplimiento de normativas de seguridad de la industria y las mejores prácticas de IBM Cloud exigen que las credenciales de acceso que no se hayan utilizado durante un periodo prolongado (típicamente 180 días) sean desactivadas o eliminadas para minimizar el riesgo de uso indebido. + +**Terraform no tiene visibilidad sobre el historial de uso en tiempo real** ni sobre la telemetría de autenticación de las claves que gestiona. Por lo tanto, esta regla actúa como un recordatorio crítico para que el equipo de seguridad implemente procesos de monitoreo externos (como scripts de auditoría con la CLI de IBM Cloud o integraciones con el Activity Tracker) que detecten y reaccionen ante claves inactivas. + +## Lógica de la Regla + +La política realiza las siguientes acciones: +1. Identifica la creación de cualquier recurso `ibm_iam_api_key`. +2. Identifica la creación de cualquier recurso `ibm_iam_service_api_key`. +3. Genera una alerta informativa para cada clave detectada, instando al auditor a verificar que existe una política de ciclo de vida activa. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: API Key de Usuario Creada + +* **Descripción:** Se ha definido una clave de API personal. Estas claves suelen tener privilegios amplios y deben ser vigiladas. +* **Ejemplo de Código Terraform:** + ```terraform + resource "ibm_iam_api_key" "my_key" { + name = "user-api-key" + } + ``` +* **Ubicación de la Alerta:** Recurso `ibm_iam_api_key`. + +--- + +### Caso 2: API Key de Service ID Creada + +* **Descripción:** Se ha definido una clave para una aplicación o servicio automatizado. +* **Ejemplo de Código Terraform:** + ```terraform + resource "ibm_iam_service_api_key" "service_key" { + name = "app-service-key" + service_id_crn = ibm_iam_service_id.serviceID.crn + } + ``` +* **Ubicación de la Alerta:** Recurso `ibm_iam_service_api_key`. + +## Recursos Involucrados + +* `ibm_iam_api_key` +* `ibm_iam_service_api_key` + +## Solución + +Establezca un proceso automatizado o una revisión periódica (fuera de Terraform) que consulte el estado de las claves. Puede usar la CLI de IBM Cloud para identificar claves inactivas: + +```bash +# Ejemplo: Listar claves de API y verificar el campo 'Last Used' +ibmcloud iam api-keys --output json \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json new file mode 100644 index 00000000000..c9c10f6d76a --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "a2b88f1a-038f-4898-a7c1-61eb2aa41143", + "queryName": "IBM Cloud API Keys Unused for 180 Days (Manual)", + "severity": "INFO", + "category": "Observability", + "descriptionText": "Terraform cannot detect if an IBM Cloud IAM API Key is unused. This rule flags the creation of API Keys to remind the auditor to establish an automated process to detect and disable keys unused for 180 days.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_api_key", + "platform": "Terraform", + "descriptionID": "a2b88f1a", + "cloudProvider": "ibm", + "cwe": "CWE-798", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/query.rego b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/query.rego new file mode 100644 index 00000000000..76f1454c05a --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/query.rego @@ -0,0 +1,29 @@ +package Cx + +# CASO 1: IBM Cloud IAM API Key (Usuario). +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.ibm_iam_api_key[name] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_iam_api_key.%s", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "An external process should monitor and disable this key if unused for 180 days", + "keyActualValue": "IBM IAM User API Key created via Terraform. Manual verification of lifecycle policy required.", + } +} + +# CASO 2: IBM Cloud IAM Service API Key (Service ID). +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.ibm_iam_service_api_key[name] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_iam_service_api_key.%s", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "An external process should monitor and disable this key if unused for 180 days", + "keyActualValue": "IBM IAM Service API Key created via Terraform. Manual verification of lifecycle policy required.", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/negative1.tf new file mode 100644 index 00000000000..28dbe58cfe0 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/negative1.tf @@ -0,0 +1,8 @@ +# El cumplimiento es "negativo" cuando no hay recursos de claves de API que requieran monitoreo de ciclo de vida. +resource "ibm_is_vpc" "safe_vpc" { + name = "compliant-vpc" +} + +resource "ibm_iam_access_group" "acc_group" { + name = "test-group" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive1.tf new file mode 100644 index 00000000000..bbcaa0dfd23 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive1.tf @@ -0,0 +1,3 @@ +resource "ibm_iam_api_key" "personal_key" { + name = "admin-key" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive2.tf b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive2.tf new file mode 100644 index 00000000000..e2d54fb69f0 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive2.tf @@ -0,0 +1,4 @@ +resource "ibm_iam_service_api_key" "app_key" { + name = "automation-key" + service_id_crn = "crn:v1:bluemix:public:iam-identity::a/123::serviceid:ServiceId-123" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..e17a67b4b7b --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "IBM Cloud API Keys Unused for 180 Days (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "IBM Cloud API Keys Unused for 180 Days (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/README.md b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/README.md new file mode 100644 index 00000000000..fa1c74979f2 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/README.md @@ -0,0 +1,50 @@ +# Regla KICS: IBM Owner Account API Key (Manual) + +## Descripción General + +Esta regla informativa (INFO) detecta la creación de claves de API de usuario (`ibm_iam_api_key`) en IBM Cloud para mitigar riesgos de privilegios excesivos. + +Según las mejores prácticas de seguridad, como el **IBM Cloud Foundations Benchmark**, la cuenta propietaria (**Account Owner**) no debe tener claves de API activas. El propietario tiene privilegios absolutos sobre la facturación, gestión de identidades y la eliminación total de la cuenta. Las claves de API eluden el control de MFA (Autenticación Multi-Factor), por lo que una clave de propietario comprometida otorga control total e irreversible a un atacante. + +## Lógica de la Regla + +1. Identifica recursos del tipo `ibm_iam_api_key`. +2. Genera una alerta informativa que requiere validación manual. Dado que Terraform no tiene visibilidad del rol del usuario (Owner o no) en tiempo de escaneo estático, la regla alerta sobre cualquier clave de usuario creada. +3. Esta regla **excluye** las claves de Service ID (`ibm_iam_service_api_key`), ya que estas son la alternativa segura recomendada y no pueden poseer el rol de "Account Owner". + +## Casos de Fallo Detectados + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso 1: API Key de Usuario (Potencial Owner) + +* **Descripción:** Se ha creado una clave de API personal. Se debe confirmar que el usuario que emite la clave no sea el propietario de la cuenta. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_iam_api_key" "personal_key" { + name = "admin-key" + } + ``` +* **Ubicación de la Alerta:** Recurso `ibm_iam_api_key`. + +## Recurso Involucrado + +* `ibm_iam_api_key` + +## Solución + +1. Verifique en la consola de IAM que el usuario asociado a la clave no es el "Account Owner". +2. Si lo es, elimine la clave y utilice un **Service ID** con permisos limitados mediante el principio de mínimo privilegio. + +```terraform +# RECOMENDADO: Usar Service ID para automatizaciones +resource "ibm_iam_service_id" "app_identity" { + name = "app-automation-id" +} + +resource "ibm_iam_service_api_key" "app_key" { + name = "automation-key" + iam_service_id = ibm_iam_service_id.app_identity.iam_id +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json new file mode 100644 index 00000000000..b0a60a9691d --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "dae483b9-d462-49d1-993c-4d398cad281e", + "queryName": "IBM Owner Account API Key (Manual)", + "severity": "INFO", + "category": "Access Control", + "descriptionText": "The account owner should not have an associated API Key. Using owner credentials implies unlimited privileges and poses a catastrophic risk if compromised. Verify that this API Key does not belong to the Account Owner.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_api_key", + "platform": "Terraform", + "descriptionID": "dae483b9", + "cloudProvider": "ibm", + "cwe": "CWE-269", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/query.rego b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/query.rego new file mode 100644 index 00000000000..5ed5881e0d0 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/query.rego @@ -0,0 +1,15 @@ +package Cx + +# CASO 1: Detección de API Key de Usuario. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.ibm_iam_api_key[name] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_iam_api_key.%s", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The API Key should belong to a functional user or Service ID, NEVER the Account Owner", + "keyActualValue": "IBM IAM User API Key detected. Verify this key is NOT for the Account Owner.", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/negative1.tf new file mode 100644 index 00000000000..430cc21292a --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/negative1.tf @@ -0,0 +1,9 @@ +# Las claves de Service ID son el estándar seguro y no disparan esta alerta +resource "ibm_iam_service_id" "service_id" { + name = "safe-service" +} + +resource "ibm_iam_service_api_key" "service_key" { + name = "safe-key" + iam_service_id = ibm_iam_service_id.service_id.iam_id +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive1.tf new file mode 100644 index 00000000000..4c8f76627cc --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive1.tf @@ -0,0 +1,3 @@ +resource "ibm_iam_api_key" "owner_candidate_key" { + name = "potential-owner-key" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..98f50c83fc9 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "IBM Owner Account API Key (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/README.md b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/README.md new file mode 100644 index 00000000000..844fcfb4414 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/README.md @@ -0,0 +1,65 @@ +# Regla KICS: IBM IAM Policies Attached to Users (Manual) + +## Descripción General + +Esta regla informativa (INFO) detecta el uso del recurso `ibm_iam_user_policy` en Terraform. + +La asignación de permisos basada en grupos (**RBAC**) es el pilar de una gobernanza de identidades robusta. Las mejores prácticas de IBM Cloud y marcos de cumplimiento como CIS recomiendan gestionar los permisos a través de **Grupos de Acceso** (Access Groups) en lugar de asignar políticas directamente a usuarios individuales. + +La asignación directa usuario a usuario crea una infraestructura "snowflake" donde cada identidad tiene permisos únicos, lo que hace casi imposible auditar el impacto de cambios globales o garantizar el principio de mínimo privilegio. El uso de grupos facilita el "onboarding" y "offboarding" de usuarios y centraliza el control de acceso. + +## Lógica de la Regla + +1. Escanea el código de Terraform en busca del recurso `ibm_iam_user_policy`. +2. Genera una alerta para cada ocurrencia detectada. +3. El auditor debe verificar si esta asignación directa está realmente justificada (como en el caso de cuentas de administración de emergencia o "break-glass") o si debe ser refactorizada para integrarse en un grupo de acceso. + +## Casos de Fallo Detectados + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso 1: Asignación de Política Directa a Usuario + +* **Descripción:** Se utiliza el recurso `ibm_iam_user_policy` para otorgar roles a una identidad de usuario específica. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_iam_user_policy" "direct_access" { + ibm_id = "user@example.com" + roles = ["Administrator"] + + resources { + service = "is" + } + } + ``` +* **Ubicación de la Alerta:** Recurso `ibm_iam_user_policy`. + +## Recurso Involucrado + +* `ibm_iam_user_policy` + +## Solución + +La práctica recomendada consiste en crear un grupo de acceso, asignar la política a dicho grupo y posteriormente añadir a los usuarios como miembros. + +```terraform +# PATRÓN CORRECTO Y ESCALABLE +resource "ibm_iam_access_group" "admins" { + name = "Cloud-Administrators" +} + +resource "ibm_iam_access_group_policy" "admin_policy" { + access_group_id = ibm_iam_access_group.admins.id + roles = ["Administrator"] + + resources { + service = "is" + } +} + +resource "ibm_iam_access_group_members" "admin_members" { + access_group_id = ibm_iam_access_group.admins.id + ibm_ids = ["user@example.com"] +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json new file mode 100644 index 00000000000..97aee910dd5 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "d08b8443-aa59-4099-9523-5cfc6bee1d4a", + "queryName": "IBM IAM Policies Attached to Users (Manual)", + "severity": "INFO", + "category": "Access Control", + "descriptionText": "Detects usage of 'ibm_iam_user_policy'. Access policies should be assigned to Access Groups ('ibm_iam_access_group_policy') rather than directly to users to ensure scalable and manageable IAM governance.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_user_policy", + "platform": "Terraform", + "descriptionID": "d08b8443", + "cloudProvider": "ibm", + "cwe": "CWE-284", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/query.rego b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/query.rego new file mode 100644 index 00000000000..6c640e7996c --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/query.rego @@ -0,0 +1,15 @@ +package Cx + +# CASO 1: Detección de políticas directas a usuario. +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.ibm_iam_user_policy[name] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_iam_user_policy.%s", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "IAM policies should be assigned to Access Groups, not users", + "keyActualValue": "Direct user policy assignment detected. Manual review required to justify exception.", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/negative1.tf new file mode 100644 index 00000000000..7febdcd80cc --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/negative1.tf @@ -0,0 +1,14 @@ +# Uso correcto de políticas mediante grupos de acceso +resource "ibm_iam_access_group" "auditors" { + name = "Audit-Team" +} + +resource "ibm_iam_access_group_policy" "group_policy" { + access_group_id = ibm_iam_access_group.auditors.id + roles = ["Viewer"] +} + +resource "ibm_iam_access_group_members" "members" { + access_group_id = ibm_iam_access_group.auditors.id + ibm_ids = ["auditor@company.com"] +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive1.tf new file mode 100644 index 00000000000..cbbb7c042be --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive1.tf @@ -0,0 +1,8 @@ +resource "ibm_iam_user_policy" "insecure_policy" { + ibm_id = "auditor@company.com" + roles = ["Viewer"] + + resources { + resource_type = "resource-group" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..fb108f03019 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "IBM IAM Policies Attached to Users (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/README.md b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/README.md new file mode 100644 index 00000000000..7f68b7b9667 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/README.md @@ -0,0 +1,50 @@ +# Regla KICS: Restrict API Key & Service ID Creation (Manual) + +## Descripción General + +Esta regla informativa (INFO) audita las asignaciones de roles en **IBM Cloud IAM** para asegurar que la capacidad de crear identidades y credenciales esté estrictamente controlada. + +Según los controles de seguridad **CIS IBM Cloud Foundations**, la creación de **claves de API de usuario** y **Service IDs** es una acción de alto privilegio que debe restringirse a un número mínimo de usuarios de confianza. En IBM Cloud, roles predefinidos de plataforma como `Administrator` o `Editor` sobre el servicio de identidad incluyen permisos potentes como `iam.service_id.create` o `iam.api_key.create`. + +Esta regla identifica las definiciones de políticas para que un auditor verifique que estos roles no se estén asignando de forma masiva o a sujetos que no requieren capacidades administrativas de identidad, cumpliendo con el **Principio de Mínimo Privilegio**. + +## Lógica de la Regla + +La política realiza las siguientes acciones: +1. Identifica recursos `ibm_iam_user_policy` y `ibm_iam_access_group_policy`. +2. Extrae y evalúa la lista de roles asignados en cada política. +3. Genera una alerta para que se verifique manualmente si los roles asignados (especialmente Administrator o Editor) son estrictamente necesarios para el propósito del usuario o grupo. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Revisión de Roles en Políticas de Usuario +* **Descripción:** Se asignan roles directamente a una identidad de usuario. +* **Ubicación de la Alerta:** Atributo `roles` dentro de `ibm_iam_user_policy`. + +### Caso 2: Revisión de Roles en Políticas de Grupo +* **Descripción:** Se asignan roles a un Grupo de Acceso (Access Group), afectando a todos sus miembros. +* **Ubicación de la Alerta:** Atributo `roles` dentro de `ibm_iam_access_group_policy`. + +## Recurso Involucrado + +* `ibm_iam_user_policy` +* `ibm_iam_access_group_policy` + +## Solución + +Revisa los roles asignados. Evita otorgar roles de plataforma amplios como `Editor` o `Administrator` de forma generalizada. Si un usuario solo necesita gestionar recursos existentes, utiliza el rol `Operator` o `Viewer`. Si se requiere una granularidad mayor, implemente **Roles Personalizados (Custom Roles)** que omitan específicamente las acciones de creación de identidades. + +```terraform +# Ejemplo de política restrictiva usando roles de menor privilegio +resource "ibm_iam_access_group_policy" "restricted_group_policy" { + access_group_id = ibm_iam_access_group.group.id + roles = ["Viewer", "Operator"] # Roles que no permiten creación de IDs/Keys + + resources { + service = "is" # VPC Infrastructure + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json new file mode 100644 index 00000000000..8f2aba14b52 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "30640fc8-88be-4053-882c-55fd0febaf3f", + "queryName": "Restrict API Key & Service ID Creation (Manual)", + "severity": "INFO", + "category": "Access Control", + "descriptionText": "CIS controls recommend restricting the creation of API Keys and Service IDs to privileged users only. Review IAM policies to ensure 'Editor' or 'Administrator' roles (or custom roles with creation actions) are not granted broadly.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_user_policy", + "platform": "Terraform", + "descriptionID": "30640fc8", + "cloudProvider": "ibm", + "cwe": "CWE-276", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/query.rego b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/query.rego new file mode 100644 index 00000000000..d60ab79cae8 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/query.rego @@ -0,0 +1,38 @@ +package Cx + +ensure_array(x) = x { is_array(x) } +ensure_array(x) = [x] { not is_array(x) } + +# CASO 1: Revisión de Políticas de Usuario (ibm_iam_user_policy). +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.ibm_iam_user_policy[name] + + roles := ensure_array(policy.roles) + count(roles) > 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_iam_user_policy.%s.roles", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Roles should not grant 'iam.service_id.create' or 'iam.api_key.create' to non-privileged users", + "keyActualValue": sprintf("User policy grants roles: %v. Manual review required.", [roles]), + } +} + +# CASO 2: Revisión de Políticas de Grupo de Acceso (ibm_iam_access_group_policy). +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.ibm_iam_access_group_policy[name] + + roles := ensure_array(policy.roles) + count(roles) > 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_iam_access_group_policy.%s.roles", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Roles should not grant 'iam.service_id.create' or 'iam.api_key.create' to non-privileged users", + "keyActualValue": sprintf("Access Group policy grants roles: %v. Manual review required.", [roles]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/negative1.tf new file mode 100644 index 00000000000..6f3d0627404 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/negative1.tf @@ -0,0 +1,4 @@ +# El cumplimiento es "negativo" cuando no hay políticas de IAM que auditar en este contexto. +resource "ibm_is_vpc" "example_vpc" { + name = "compliant-network" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive1.tf new file mode 100644 index 00000000000..8f249923af7 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive1.tf @@ -0,0 +1,8 @@ +resource "ibm_iam_user_policy" "high_privilege_user" { + ibm_id = "user@example.com" + roles = ["Administrator"] # Alerta: requiere revisión manual + + resources { + service = "iam-identity" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive2.tf b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive2.tf new file mode 100644 index 00000000000..372270cfa91 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive2.tf @@ -0,0 +1,8 @@ +resource "ibm_iam_access_group_policy" "broad_group_policy" { + access_group_id = "access-group-id" + roles = ["Editor", "Viewer"] # Alerta: Editor permite creación de credenciales + + resources { + service = "iam-identity" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..f0aa46eaf5e --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Restrict API Key & Service ID Creation (Manual)", + "severity": "INFO", + "line": 3, + "fileName": "positive1.tf" + }, + { + "queryName": "Restrict API Key & Service ID Creation (Manual)", + "severity": "INFO", + "line": 3, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/README.md b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/README.md new file mode 100644 index 00000000000..fc8fc907db3 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/README.md @@ -0,0 +1,56 @@ +# Regla KICS: IBM Account Session Expiration Too Long + +## Descripción General + +Esta regla de severidad **MEDIA** verifica que la **Expiración de Sesión** en la configuración de la cuenta de IBM Cloud esté configurada de manera segura para mitigar riesgos de seguridad de identidad. + +Por defecto, o si se configura de forma laxa, las sesiones de usuario pueden permanecer activas durante periodos prolongados (hasta 24 horas). Esto aumenta considerablemente la ventana de oportunidad para ataques de secuestro de sesión (Session Hijacking) y accesos no autorizados en terminales físicas compartidas. Según las mejores prácticas de la industria y el **CIS IBM Cloud Foundations Benchmark**, se recomienda limitar la duración de la sesión a **3600 segundos (1 hora)** o menos para forzar una re-autenticación periódica. + +## Lógica de la Regla + +La política audita el recurso `ibm_iam_account_settings` realizando dos comprobaciones: +1. **Validación de Presencia:** Si falta el atributo `session_expiration_in_seconds`, la regla falla al asumir que la cuenta depende de valores por defecto inseguros. +2. **Validación de Valor:** Si el valor configurado es numéricamente superior a `3600` segundos, la regla falla. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Configuración de Expiración Ausente +* **Descripción:** El recurso existe pero no define el tiempo de vida de la sesión, delegando el control al proveedor. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_iam_account_settings" "insecure_default" { + mfa = "LEVEL2" + # Falta session_expiration_in_seconds + } + ``` +* **Ubicación de la Alerta:** Bloque del recurso `ibm_iam_account_settings`. + +--- + +### Caso 2: Tiempo de Sesión Excesivo +* **Descripción:** La sesión se ha configurado con una duración mayor a la hora recomendada (ej. 8 horas o 24 horas). +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_iam_account_settings" "too_long" { + session_expiration_in_seconds = 28800 # 8 horas + } + ``` +* **Ubicación de la Alerta:** Atributo `session_expiration_in_seconds`. + +## Recurso Involucrado + +* `ibm_iam_account_settings` + +## Solución + +Asegúrese de definir el límite de sesión en 3600 segundos o menos para cumplir con los estándares de seguridad. + +```terraform +resource "ibm_iam_account_settings" "compliant_settings" { + mfa = "LEVEL2" + session_expiration_in_seconds = 3600 # 1 Hora +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json new file mode 100644 index 00000000000..3cd3a3c7988 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "3d6db2d6-fa2d-41df-a783-d3dee76f717f", + "queryName": "IBM Account Session Expiration Too Long", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that the IBM Cloud account session expiration is configured to a secure limit (e.g., 3600 seconds / 1 hour). Long session timeouts increase the risk of session hijacking.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_account_settings", + "platform": "Terraform", + "descriptionID": "3d6db2d6", + "cloudProvider": "ibm", + "cwe": "CWE-613", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/query.rego b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/query.rego new file mode 100644 index 00000000000..d374d167dda --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/query.rego @@ -0,0 +1,35 @@ +package Cx + +# REGLA 1: Falta el atributo 'session_expiration_in_seconds'. +CxPolicy[result] { + doc := input.document[i] + settings := doc.resource.ibm_iam_account_settings[name] + + object.get(settings, "session_expiration_in_seconds", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_iam_account_settings.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'session_expiration_in_seconds' should be defined and set to 3600 (1 hour) or less", + "keyActualValue": "'session_expiration_in_seconds' is missing (using insecure default)", + } +} + +# REGLA 2: La sesión dura más de 1 hora (3600 segundos). +CxPolicy[result] { + doc := input.document[i] + settings := doc.resource.ibm_iam_account_settings[name] + + expiration := to_number(settings.session_expiration_in_seconds) + + expiration > 3600 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_iam_account_settings.%s.session_expiration_in_seconds", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'session_expiration_in_seconds' should be <= 3600", + "keyActualValue": sprintf("'session_expiration_in_seconds' is set to '%v'", [expiration]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/negative1.tf b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/negative1.tf new file mode 100644 index 00000000000..bb5077c463f --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/negative1.tf @@ -0,0 +1,4 @@ +resource "ibm_iam_account_settings" "settings_secure" { + mfa = "LEVEL2" + session_expiration_in_seconds = 3600 # 1 Hora +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive1.tf b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive1.tf new file mode 100644 index 00000000000..2fe6df87104 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive1.tf @@ -0,0 +1,3 @@ +resource "ibm_iam_account_settings" "settings_missing_attr" { + mfa = "LEVEL2" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive2.tf b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive2.tf new file mode 100644 index 00000000000..b12be11ded2 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive2.tf @@ -0,0 +1,3 @@ +resource "ibm_iam_account_settings" "settings_too_long" { + session_expiration_in_seconds = 86400 # 24 Horas +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive_expected_result.json new file mode 100644 index 00000000000..cccff9041d8 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "IBM Account Session Expiration Too Long", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "IBM Account Session Expiration Too Long", + "severity": "MEDIUM", + "line": 2, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/README.md b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/README.md new file mode 100644 index 00000000000..c47c34a27be --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/README.md @@ -0,0 +1,55 @@ +# Regla KICS: Logging Habilitado para Clusters de IKS + +## Descripción General + +Esta regla de KICS para Terraform asegura que cada clúster de IBM Cloud Kubernetes Service (`ibm_container_cluster`) tenga una configuración de logging de IBM Cloud Log Analysis (`ibm_ob_logging_config`) correctamente asociada. + +La agregación de logs de un clúster de Kubernetes es una práctica fundamental para la observabilidad y la seguridad. Permite a los equipos de desarrollo y operaciones centralizar los logs de los contenedores, los nodos y los componentes del sistema. Sin esta configuración, el análisis forense tras un incidente de seguridad o la resolución de errores en aplicaciones distribuidas se vuelve extremadamente compleja. + +## Lógica de la Regla + +La política implementa una lógica de correlación de recursos en todo el proyecto. Su función es identificar cualquier instancia de `ibm_container_cluster` que no esté referenciada en el atributo `scope` de ningún recurso `ibm_ob_logging_config`. La conexión se considera válida cuando el nombre o CRN del clúster aparece en el alcance (scope) de la configuración de observabilidad. + +## Casos de Fallo Detectados + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso Único: Configuración de Logging Ausente para un Clúster + +* **Descripción:** Esta regla detecta cualquier clúster de IKS que se esté aprovisionando sin su correspondiente pieza de telemetría para logs. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_container_cluster" "orphan_cluster" { + name = "my-production-cluster" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + # No existe un recurso ibm_ob_logging_config que use este clúster como scope + } + ``` +* **Ubicación de la Alerta:** La alerta señalará directamente al bloque de código del recurso `ibm_container_cluster` huérfano de configuración de logs. + +## Recursos Involucrados + +* `ibm_container_cluster` +* `ibm_ob_logging_config` + +## Solución + +Para solucionar los problemas detectados, asegúrese de que para cada clúster exista un recurso `ibm_ob_logging_config` que vincule el clúster con una instancia de Log Analysis. + +```terraform +resource "ibm_ob_logging_config" "cluster_telemetry" { + # Vincular con el clúster mediante su CRN o ID + scope = ibm_container_cluster.my_cluster.crn + instance = ibm_resource_instance.log_analysis_inst.guid +} + +resource "ibm_resource_instance" "log_analysis_inst" { + name = "log-aggregator" + service = "logdna" + plan = "7-day" + location = "us-south" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json new file mode 100644 index 00000000000..5461ea44b9c --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "e55a0224-47b8-41a8-8cc1-8c8581e13a8d", + "queryName": "IKS Cluster Logging Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that every IBM Cloud Kubernetes Service (IKS) cluster has an associated logging service configuration. Centralized logging is essential for troubleshooting applications, monitoring cluster activity, and performing security analysis.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/ob_logging_config", + "platform": "Terraform", + "descriptionID": "e55a0224", + "cloudProvider": "ibm", + "cwe": "CWE-778", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/query.rego b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/query.rego new file mode 100644 index 00000000000..26b576f814a --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/query.rego @@ -0,0 +1,21 @@ +package Cx + +CxPolicy[result] { + doc := input.document[i] + _ := doc.resource.ibm_container_cluster[cluster_name] + + matching_configs := [config | + config := input.document[_].resource.ibm_ob_logging_config[_] + contains(config.scope, cluster_name) + ] + + count(matching_configs) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_container_cluster.%s", [cluster_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "ibm_container_cluster should have an associated ibm_ob_logging_config resource", + "keyActualValue": "ibm_container_cluster does not have an associated ibm_ob_logging_config resource", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/negative1.tf b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/negative1.tf new file mode 100644 index 00000000000..38a35202e55 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/negative1.tf @@ -0,0 +1,13 @@ +resource "ibm_container_cluster" "secure_cluster" { + name = "compliant-cluster" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + public_vlan_id = "123" + private_vlan_id = "456" +} + +resource "ibm_ob_logging_config" "logging_ok" { + scope = ibm_container_cluster.secure_cluster.crn + instance = "crn:v1:bluemix:public:logdna:..." +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/positive1.tf b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/positive1.tf new file mode 100644 index 00000000000..c940fb487ab --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/positive1.tf @@ -0,0 +1,8 @@ +resource "ibm_container_cluster" "cluster_without_logs" { + name = "vulnerable-cluster" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + public_vlan_id = "123" + private_vlan_id = "456" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..64f347ff4ab --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "IKS Cluster Logging Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/README.md b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/README.md new file mode 100644 index 00000000000..c3ff1801860 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/README.md @@ -0,0 +1,55 @@ +# Regla KICS: Monitorización Habilitada para Clusters de IKS + +## Descripción General + +Esta regla de KICS para Terraform asegura que cada clúster de IBM Cloud Kubernetes Service (`ibm_container_cluster`) tenga una configuración de monitorización de **IBM Cloud Monitoring** (`ibm_ob_monitoring_config`) vinculada. + +La monitorización de un clúster de Kubernetes es un requisito crítico para la operatividad y estabilidad. Permite obtener métricas en tiempo real sobre el uso de CPU, memoria, tráfico de red y latencia de los servicios. Sin esta visibilidad, los equipos de operaciones no pueden detectar cuellos de botella, prever la saturación de recursos mediante escalado automático, ni responder proactivamente a incidentes de salud en la infraestructura. + +## Lógica de la Regla + +La política implementa una lógica de correlación cruzada en el documento de Terraform. Identifica cualquier recurso `ibm_container_cluster` que no sea referenciado en el atributo `scope` de ningún recurso `ibm_ob_monitoring_config`. La vinculación se valida cuando el nombre o el CRN del clúster se incluye en el ámbito de la configuración de monitorización. + +## Casos de Fallo Detectados + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso Único: Configuración de Monitorización Ausente para un Clúster + +* **Descripción:** El clúster se aprovisiona sin los agentes o la vinculación necesaria para enviar métricas al servicio de monitorización centralizado de IBM Cloud. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_container_cluster" "cluster_unmonitored" { + name = "production-iks-cluster" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + # No existe un recurso ibm_ob_monitoring_config apuntando a este clúster + } + ``` +* **Ubicación de la Alerta:** La alerta señalará directamente al bloque de código del recurso `ibm_container_cluster` huérfano de monitorización. + +## Recursos Involucrados + +* `ibm_container_cluster` +* `ibm_ob_monitoring_config` + +## Solución + +Para solucionar esta alerta, debe existir un recurso `ibm_ob_monitoring_config` que conecte el clúster con una instancia de monitorización (basada en Sysdig). + +```terraform +resource "ibm_ob_monitoring_config" "monitoring_setup" { + # Relación directa con el clúster + scope = ibm_container_cluster.my_cluster.crn + instance = ibm_resource_instance.sysdig_instance.guid +} + +resource "ibm_resource_instance" "sysdig_instance" { + name = "cluster-metrics-aggregator" + service = "sysdig-monitor" + plan = "graduated-tier" + location = "us-south" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json new file mode 100644 index 00000000000..5b72713ac11 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "51bac252-399d-49d0-bfa5-0bd52194fed9", + "queryName": "IKS Cluster Monitoring Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that every IBM Cloud Kubernetes Service (IKS) cluster has an associated monitoring service configuration. Monitoring is essential for observing cluster health, performance, and resource utilization.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/ob_monitoring_config", + "platform": "Terraform", + "descriptionID": "51bac252", + "cloudProvider": "ibm", + "cwe": "CWE-778", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/query.rego b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/query.rego new file mode 100644 index 00000000000..a0006913788 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/query.rego @@ -0,0 +1,22 @@ +package Cx + +# REGLA: Detectar clústeres de IKS sin configuración de monitorización asociada. +CxPolicy[result] { + doc := input.document[i] + _ := doc.resource.ibm_container_cluster[cluster_name] + + matching_configs := [config | + config := input.document[_].resource.ibm_ob_monitoring_config[_] + contains(config.scope, cluster_name) + ] + + count(matching_configs) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_container_cluster.%s", [cluster_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "ibm_container_cluster should have an associated ibm_ob_monitoring_config resource", + "keyActualValue": "ibm_container_cluster does not have an associated ibm_ob_monitoring_config resource", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/negative1.tf b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/negative1.tf new file mode 100644 index 00000000000..51f8af06e4f --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/negative1.tf @@ -0,0 +1,11 @@ +resource "ibm_container_cluster" "aks_with_monitoring" { + name = "visible-cluster" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" +} + +resource "ibm_ob_monitoring_config" "monitoring_ok" { + scope = ibm_container_cluster.aks_with_monitoring.crn + instance = "crn:v1:bluemix:public:sysdig-monitor:..." +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/positive1.tf b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/positive1.tf new file mode 100644 index 00000000000..7e884c04be2 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/positive1.tf @@ -0,0 +1,8 @@ +resource "ibm_container_cluster" "aks_no_monitoring" { + name = "blind-cluster" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + public_vlan_id = "vlan1" + private_vlan_id = "vlan2" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..86cd6bc3981 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "IKS Cluster Monitoring Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/README.md b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/README.md new file mode 100644 index 00000000000..b0f3d5b5695 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/README.md @@ -0,0 +1,51 @@ +# Regla KICS: IBM Instance OS Disk Encryption (Manual) + +## Descripción General + +Esta regla informativa (INFO) audita las instancias de servidor virtual (**VSI**) de la infraestructura VPC (`ibm_is_instance`) para verificar que el cifrado del disco de arranque esté bajo el control del cliente. + +Por defecto, IBM Cloud cifra el volumen de arranque (boot volume) de cada instancia utilizando claves gestionadas por el proveedor. Sin embargo, para cumplir con estándares de seguridad avanzados como **FIPS 140-2**, o normativas financieras y gubernamentales, se requiere el uso de **Customer Managed Keys (CMK)** o **Keep Your Own Key (KYOK)**. + +Al proporcionar el CRN de una clave de **Key Protect** o **Hyper Protect Crypto Services** en la configuración de la instancia, el cliente obtiene la capacidad de revocar el acceso a los datos del sistema operativo de forma instantánea. + +## Lógica de la Regla + +La política evalúa el recurso `ibm_is_instance` bajo dos escenarios: +1. **Ausencia de Configuración de Volumen:** Si el bloque `boot_volume` no está presente, la instancia se crea con parámetros por defecto (cifrado gestionado por IBM). +2. **Ausencia de Clave de Cifrado:** Si el bloque `boot_volume` existe pero el parámetro `encryption` no está definido, se considera que el volumen no está utilizando claves gestionadas por el cliente. + +## Casos de Fallo Detectados + +A continuación se describen los escenarios que esta política detectará. + +--- + +### Caso 1: Cifrado por Defecto (Bloque Ausente) +* **Descripción:** No se define configuración de disco de arranque, delegando el cifrado a IBM Cloud. +* **Ubicación de la Alerta:** Bloque del recurso `ibm_is_instance`. + +### Caso 2: Cifrado por Defecto (Atributo Ausente) +* **Descripción:** Se configura el volumen de arranque pero se omite la clave de cifrado. +* **Ubicación de la Alerta:** Atributo `boot_volume`. + +## Recurso Involucrado + +* `ibm_is_instance` + +## Solución + +Defina el bloque `boot_volume` e incluya el CRN de su clave raíz de Key Protect en el argumento `encryption`. + +```terraform +resource "ibm_is_instance" "secure_vsi" { + name = "secure-production-server" + image = "r006-723f851b-4043-42e5-9467-33a39e802375" + profile = "bx2-2x8" + + boot_volume { + name = "os-disk-secure" + encryption = "crn:v1:bluemix:public:kms:us-south:a/aaaa:bbbb:key:cccc" + } + + # ... otros parámetros de red y vpc ... +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/metadata.json b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/metadata.json new file mode 100644 index 00000000000..3a961663e59 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "86f1560c-74cb-48a3-ad5a-7da25cab4d03", + "queryName": "IBM Instance OS Disk Encryption (Manual)", + "severity": "INFO", + "category": "Encryption", + "descriptionText": "The Virtual Server Instance boot volume (OS Disk) relies on default provider-managed encryption. It is not configured with 'boot_volume.encryption', which is required for Customer Managed Keys (CMK), BYOK, or KYOK.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_instance", + "platform": "Terraform", + "descriptionID": "86f1560c", + "cloudProvider": "ibm", + "cwe": "CWE-312", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/query.rego b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/query.rego new file mode 100644 index 00000000000..0ad2c6fd738 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/query.rego @@ -0,0 +1,39 @@ +package Cx + +ensure_array(x) = x { is_array(x) } +ensure_array(x) = [x] { not is_array(x) } + +# CASO 1: Bloque 'boot_volume' totalmente ausente. +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.ibm_is_instance[name] + + not instance.boot_volume + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_is_instance.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'boot_volume' block should be defined with 'encryption' set to a CRN", + "keyActualValue": "'boot_volume' block is missing (using default encryption)", + } +} + +# CASO 2: Bloque 'boot_volume' presente, pero falta 'encryption'. +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.ibm_is_instance[name] + + boot_volumes := ensure_array(instance.boot_volume) + boot_vol := boot_volumes[_] + + object.get(boot_vol, "encryption", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_is_instance.%s.boot_volume", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'boot_volume.encryption' attribute should be defined with a Key Protect/HPCS CRN", + "keyActualValue": "'encryption' is missing in boot_volume (using default encryption)", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/negative1.tf new file mode 100644 index 00000000000..7d0952a2787 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/negative1.tf @@ -0,0 +1,10 @@ +resource "ibm_is_instance" "vsi_secure" { + name = "vsi-secure" + image = "r006-12345678" + profile = "bx2-2x8" + + boot_volume { + name = "boot-disk-cmk" + encryption = "crn:v1:bluemix:public:kms:us-south:a/test:test:key:test" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive1.tf new file mode 100644 index 00000000000..717981e213b --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive1.tf @@ -0,0 +1,8 @@ +resource "ibm_is_instance" "vsi_no_boot_block" { + name = "vsi-default" + image = "r006-12345678" + profile = "bx2-2x8" + vpc = "vpc-id" + zone = "us-south-1" + keys = ["key-id"] +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive2.tf b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive2.tf new file mode 100644 index 00000000000..fdce8605450 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive2.tf @@ -0,0 +1,10 @@ +resource "ibm_is_instance" "vsi_no_encryption" { + name = "vsi-unprotected-boot" + image = "r006-12345678" + profile = "bx2-2x8" + + boot_volume { + name = "boot-disk-standard" + # FALLO: Falta atributo encryption + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..789fc08718a --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "IBM Instance OS Disk Encryption (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "IBM Instance OS Disk Encryption (Manual)", + "severity": "INFO", + "line": 6, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/README.md b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/README.md new file mode 100644 index 00000000000..743a0644829 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/README.md @@ -0,0 +1,63 @@ +# Regla KICS: Rotación Automática de Claves en IBM Key Protect + +## Descripción General + +Esta regla de KICS para Terraform asegura que todas las claves gestionadas por el cliente (`ibm_kms_key`) en **IBM Key Protect** tengan una política de rotación automática habilitada y configurada correctamente. + +La rotación periódica de claves criptográficas es una práctica de seguridad fundamental que responde al principio de **Criptografía Ágil**. El objetivo principal es limitar el "radio de explosión" (blast radius): al rotar la clave periódicamente, se reduce drásticamente la cantidad de datos que podrían ser descifrados en el hipotético caso de que el material de una clave específica se viera comprometido. Además, forzar rotaciones regulares garantiza que los procesos operativos sean capaces de manejar el ciclo de vida de las claves sin depender de una única clave estática de duración indefinida. + +## Lógica de la Regla + +La política audita el recurso `ibm_kms_key` cubriendo tres escenarios de riesgo: +1. **Ausencia de Bloque:** Detecta si no se ha definido el bloque `rotation_policy`. +2. **Atributo Faltante:** Detecta si el bloque existe pero omite el intervalo de tiempo. +3. **Valor Inválido/Cero:** Detecta si el intervalo se ha configurado en `0`, lo cual desactiva funcionalmente la rotación. + +## Casos de Fallo Detectados + +A continuación se describen los tres escenarios que esta política detectará. + +--- + +### Caso 1: Bloque `rotation_policy` Ausente +* **Descripción:** El recurso de clave existe pero no contiene ninguna instrucción de rotación automática. +* **Ejemplo de Código Terraform:** + ```terraform + resource "ibm_kms_key" "key_static" { + instance_id = "instance-id" + key_name = "static-key" + standard_key = false + } + ``` +* **Ubicación de la Alerta:** Bloque del recurso `ibm_kms_key`. + +--- + +### Caso 2: Atributo `rotation_interval_month` Ausente +* **Descripción:** Se define la política pero no se especifica cada cuántos meses debe ocurrir la rotación. +* **Ubicación de la Alerta:** Bloque `rotation_policy`. + +--- + +### Caso 3: Intervalo de Rotación en Cero +* **Descripción:** El intervalo está configurado en `0`, lo que inhabilita la automatización del ciclo de vida. +* **Ubicación de la Alerta:** Atributo `rotation_interval_month`. + +## Recurso Involucrado + +* `ibm_kms_key` + +## Solución + +Defina un bloque `rotation_policy` con un intervalo válido de entre 1 y 12 meses. + +```terraform +resource "ibm_kms_key" "key_compliant" { + instance_id = ibm_resource_instance.kms_instance.guid + key_name = "secure-rotating-key" + standard_key = false + + rotation_policy { + rotation_interval_month = 6 # Rota cada semestre + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json new file mode 100644 index 00000000000..be6ef0a17ba --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "cdaf415c-d1b9-4d15-8e6f-e27165b49d55", + "queryName": "KMS Key Rotation Disabled", + "severity": "HIGH", + "category": "Encryption", + "descriptionText": "Ensures that cryptographic keys in IBM Key Protect have an automated rotation policy enabled. Rotating keys periodically limits the amount of data exposed if a single key is compromised.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/kms_key#rotation_policy", + "platform": "Terraform", + "descriptionID": "cdaf415c", + "cloudProvider": "ibm", + "cwe": "CWE-320", + "riskScore": 9.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/query.rego b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/query.rego new file mode 100644 index 00000000000..1549c0c0b34 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/query.rego @@ -0,0 +1,47 @@ +package Cx + +# REGLA 1: El bloque 'rotation_policy' está completamente ausente. +CxPolicy[result] { + key := input.document[i].resource.ibm_kms_key[key_name] + + not key.rotation_policy + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_kms_key.%s", [key_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'rotation_policy' block should be present and configured", + "keyActualValue": "'rotation_policy' block is missing", + } +} + +# REGLA 2: El bloque 'rotation_policy' existe, pero le falta 'rotation_interval_month'. +CxPolicy[result] { + key := input.document[i].resource.ibm_kms_key[key_name] + + policy := key.rotation_policy + not policy.rotation_interval_month + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_kms_key.%s.rotation_policy", [key_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'rotation_interval_month' should be defined within the rotation policy", + "keyActualValue": "'rotation_interval_month' is missing", + } +} + +# REGLA 3: 'rotation_interval_month' está explícitamente configurado como 0. +CxPolicy[result] { + key := input.document[i].resource.ibm_kms_key[key_name] + + key.rotation_policy.rotation_interval_month == 0 + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_kms_key.%s.rotation_policy.rotation_interval_month", [key_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'rotation_interval_month' should be a value between 1 and 12", + "keyActualValue": "'rotation_interval_month' is set to 0, disabling rotation", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/negative1.tf b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/negative1.tf new file mode 100644 index 00000000000..a15ea09d425 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/negative1.tf @@ -0,0 +1,9 @@ +resource "ibm_kms_key" "key_secure" { + instance_id = "guid-123" + key_name = "key-compliant" + standard_key = false + + rotation_policy { + rotation_interval_month = 12 + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive1.tf b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive1.tf new file mode 100644 index 00000000000..25da7b1e36f --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive1.tf @@ -0,0 +1,5 @@ +resource "ibm_kms_key" "key_no_policy" { + instance_id = "guid-123" + key_name = "key-fails-1" + standard_key = false +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive2.tf b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive2.tf new file mode 100644 index 00000000000..0f08f497188 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive2.tf @@ -0,0 +1,9 @@ +resource "ibm_kms_key" "key_empty_policy" { + instance_id = "guid-123" + key_name = "key-fails-2" + standard_key = false + + rotation_policy { + # Falta rotation_interval_month + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive3.tf b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive3.tf new file mode 100644 index 00000000000..a7d95812dbf --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive3.tf @@ -0,0 +1,9 @@ +resource "ibm_kms_key" "key_zero_policy" { + instance_id = "guid-123" + key_name = "key-fails-3" + standard_key = false + + rotation_policy { + rotation_interval_month = 0 + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..c44e043a51f --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "KMS Key Rotation Disabled", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "KMS Key Rotation Disabled", + "severity": "HIGH", + "line": 6, + "fileName": "positive2.tf" + }, + { + "queryName": "KMS Key Rotation Disabled", + "severity": "HIGH", + "line": 7, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/README.md b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/README.md new file mode 100644 index 00000000000..8d1ae843581 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/README.md @@ -0,0 +1,53 @@ +# Regla KICS: Archivado Habilitado para IBM LogDNA + +## Descripción General + +Esta regla de KICS para Terraform asegura que cada instancia de **IBM LogDNA** (`ibm_logdna_instance`) tenga el archivado de eventos configurado mediante el recurso `ibm_logdna_archive`. + +La retención de logs a largo plazo es una exigencia crítica en marcos de cumplimiento como **PCI DSS**, **SOC 2**, o **HIPAA**. El archivado permite mover los registros de la capa de búsqueda activa a una capa de almacenamiento de bajo costo (IBM Cloud Object Storage), garantizando que los datos estén disponibles para auditorías o investigaciones forenses meses o años después de su generación, incluso si la instancia operativa de Log Analysis ha purgado los datos de su caché de búsqueda. + +## Lógica de la Regla + +La política realiza un escaneo de correlación cruzada en el proyecto de Terraform. Identifica cualquier recurso `ibm_logdna_instance` que no sea referenciado en el atributo `instance_id` de ningún recurso `ibm_logdna_archive`. El fallo se dispara ante la **omisión completa** del recurso de archivado, lo que implica un riesgo de pérdida definitiva de datos tras el periodo de retención del plan. + +## Casos de Fallo Detectados + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso Único: Recurso `ibm_logdna_archive` Ausente + +* **Descripción:** Se provisiona una instancia de logs para gestionar la actividad de la plataforma o aplicaciones, pero no se define un destino de persistencia para el archivado. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_logdna_instance" "my_logs" { + name = "prod-logs" + plan = "7-day" + target_resource_instance_id = ibm_resource_instance.logdna_inst.id + } + + # ERROR: Falta el recurso ibm_logdna_archive que apunte a 'my_logs' + ``` +* **Ubicación de la Alerta:** Bloque del recurso `ibm_logdna_instance` huérfano de archivado. + +## Recursos Involucrados + +* `ibm_logdna_instance` +* `ibm_logdna_archive` + +## Solución + +Asegúrese de vincular cada instancia de LogDNA con un recurso `ibm_logdna_archive` que apunte a un bucket de IBM Cloud Object Storage. + +```terraform +resource "ibm_logdna_archive" "archive_setup" { + instance_id = ibm_logdna_instance.my_logs.id + + cos { + api_key = var.ibmcloud_api_key + bucket = "my-archiving-bucket" + endpoint = "s3.private.us-south.cloud-object-storage.appdomain.cloud" + instance_crn = ibm_resource_instance.cos_inst.id + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json new file mode 100644 index 00000000000..5239adf0903 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "54c5b041-1902-4e19-b414-5473f1b349d2", + "queryName": "LogDNA Archiving Is Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that every IBM LogDNA instance has archiving configured through an 'ibm_logdna_archive' resource. Archiving is critical for long-term log retention, compliance, and forensic analysis.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/logdna_archive", + "platform": "Terraform", + "descriptionID": "54c5b041", + "cloudProvider": "ibm", + "cwe": "CWE-223", + "riskScore": 5.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/query.rego b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/query.rego new file mode 100644 index 00000000000..1a58771346c --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/query.rego @@ -0,0 +1,22 @@ +package Cx + +# REGLA: Detectar instancias de LogDNA que no tienen un recurso de archivado asociado. +CxPolicy[result] { + doc := input.document[i] + _ := doc.resource.ibm_logdna_instance[instance_name] + + matching_archives := [archive | + archive := input.document[_].resource.ibm_logdna_archive[_] + contains(archive.instance_id, instance_name) + ] + + count(matching_archives) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_logdna_instance.%s", [instance_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "ibm_logdna_instance should have an associated ibm_logdna_archive resource", + "keyActualValue": "ibm_logdna_instance does not have an associated ibm_logdna_archive resource", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/negative1.tf b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/negative1.tf new file mode 100644 index 00000000000..9fb2f0f9d87 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/negative1.tf @@ -0,0 +1,15 @@ +resource "ibm_logdna_instance" "logs_with_archive" { + name = "logs-with-archiver" + plan = "lite" + target_resource_instance_id = "crn:v1:bluemix:public:logdna:..." +} + +resource "ibm_logdna_archive" "archiver_ok" { + instance_id = ibm_logdna_instance.logs_with_archive.id + cos { + api_key = "secret" + bucket = "my-bucket" + endpoint = "s3.us-south.cloud-object-storage.appdomain.cloud" + instance_crn = "crn:v1:bluemix:public:cloud-object-storage:..." + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/positive1.tf b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/positive1.tf new file mode 100644 index 00000000000..15d09051bac --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/positive1.tf @@ -0,0 +1,5 @@ +resource "ibm_logdna_instance" "logs_without_archive" { + name = "logs-only-test" + plan = "lite" + target_resource_instance_id = "crn:v1:bluemix:public:logdna:..." +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..836d3c1acc4 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "LogDNA Archiving Is Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/README.md b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/README.md new file mode 100644 index 00000000000..0277252afde --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/README.md @@ -0,0 +1,51 @@ +# Regla KICS: Alertas Definidas para Vistas de IBM LogDNA + +## Descripción General + +Esta regla de severidad **BAJA** de KICS para Terraform asegura que cada vista personalizada de **IBM Log Analysis (LogDNA)** (`ibm_logdna_view`) tenga al menos una alerta (`ibm_logdna_alert`) configurada. + +Las vistas personalizadas se diseñan para filtrar y aislar eventos críticos, como errores de sistema, intentos de acceso fallidos o picos de tráfico. Sin embargo, la monitorización solo es efectiva si es proactiva. Si una vista existe pero carece de una alerta vinculada, el equipo de operaciones o seguridad depende de la revisión manual periódica de los logs, lo que aumenta drásticamente el tiempo de respuesta ante incidentes (MTTR). + +## Lógica de la Regla + +La política realiza una correlación cruzada dentro de los archivos de Terraform. Identifica cualquier recurso `ibm_logdna_view` cuyo nombre no sea referenciado en el atributo `view` de ningún recurso `ibm_logdna_alert`. La regla se activa ante la **omisión del recurso de alerta**, señalando que la vista no tiene un canal de notificación activo. + +## Casos de Fallo Detectados + +A continuación se describe el escenario que esta política detectará. + +--- + +### Caso Único: Vista de LogDNA sin Alerta Asociada + +* **Descripción:** Se define una vista específica para errores críticos o auditoría, pero no se inyecta un recurso de alerta para notificar a los responsables. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "ibm_logdna_view" "security_audit_view" { + name = "Security-Audit-Trail" + query = "app:iam-service action:login-failed" + # Error: No hay un recurso ibm_logdna_alert asociado a esta vista + } + ``` +* **Ubicación de la Alerta:** Bloque del recurso `ibm_logdna_view` huérfano de notificación. + +## Recursos Involucrados + +* `ibm_logdna_view` +* `ibm_logdna_alert` + +## Solución + +Asocie un recurso `ibm_logdna_alert` a la vista utilizando el nombre de la misma en el parámetro `view`. + +```terraform +resource "ibm_logdna_alert" "security_alert" { + name = "IAM-Failure-Alert" + view = ibm_logdna_view.security_audit_view.name + + notification_channel { + email { + recipients = ["security-ops@tu-empresa.com"] + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json new file mode 100644 index 00000000000..848cfc8ebee --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "a5107e68-028f-4b4d-9fc0-f23e3b73e448", + "queryName": "LogDNA View Without Alert", + "severity": "LOW", + "category": "Observability", + "descriptionText": "Ensures that every IBM LogDNA custom view ('ibm_logdna_view') has at least one associated alert ('ibm_logdna_alert'). Views are created to filter critical events, and without an alert, notifications for these events will not be sent.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/logdna_alert", + "platform": "Terraform", + "descriptionID": "a5107e68", + "cloudProvider": "ibm", + "cwe": "CWE-778", + "riskScore": 1.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/query.rego b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/query.rego new file mode 100644 index 00000000000..b49190804fb --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/query.rego @@ -0,0 +1,22 @@ +package Cx + +# REGLA: Detectar vistas de LogDNA que no tienen ninguna alerta asociada. +CxPolicy[result] { + doc := input.document[i] + view := doc.resource.ibm_logdna_view[view_name] + + matching_alerts := [alert | + alert := input.document[_].resource.ibm_logdna_alert[_] + contains(alert.view, view_name) + ] + + count(matching_alerts) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_logdna_view.%s", [view_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "ibm_logdna_view should have an associated ibm_logdna_alert", + "keyActualValue": "ibm_logdna_view does not have an associated ibm_logdna_alert", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/negative1.tf b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/negative1.tf new file mode 100644 index 00000000000..8518c7b77c2 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/negative1.tf @@ -0,0 +1,15 @@ +resource "ibm_logdna_view" "audit_view" { + name = "Audit-Events" + query = "service:iam" +} + +resource "ibm_logdna_alert" "audit_alert" { + name = "Audit-Alert-Policy" + view = ibm_logdna_view.audit_view.name + + notification_channel { + email { + recipients = ["admin@example.com"] + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/positive1.tf b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/positive1.tf new file mode 100644 index 00000000000..2dc3d3ec911 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/positive1.tf @@ -0,0 +1,4 @@ +resource "ibm_logdna_view" "error_view" { + name = "Critical-Errors-Only" + query = "level:error" +} \ No newline at end of file diff --git a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/positive_expected_result.json new file mode 100644 index 00000000000..dfaed345f44 --- /dev/null +++ b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "LogDNA View Without Alert", + "severity": "LOW", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/README.md new file mode 100644 index 00000000000..7c3926dad45 --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/README.md @@ -0,0 +1,95 @@ +# Regla KICS: Notificación para Problemas Detectados por Cloud Guard en OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para generar notificaciones cuando OCI Cloud Guard detecta un nuevo "problema". + +Habilitar Cloud Guard es solo el primer paso; su efectividad real depende de la capacidad del equipo de seguridad para responder a sus hallazgos. Si los problemas que Cloud Guard detecta no generan notificaciones automáticas, las alertas críticas pueden pasar desapercibidas durante un tiempo considerable, retrasando la mitigación de riesgos y aumentando la exposición. + +## Lógica de la Regla + +La política implementa una búsqueda **global** en todo el proyecto Terraform (analizando todos los archivos `.tf` simultáneamente). + +Inspecciona todos los recursos `oci_events_rule` definidos en la infraestructura para verificar si **al menos uno** de ellos cumple las siguientes condiciones: +1. Está habilitado (`is_enabled = true`). +2. Su condición de filtrado incluye el tipo de evento específico: `com.oraclecloud.cloudguard.problem`. + +Si no se encuentra ninguna regla que cumpla ambos requisitos en todo el proyecto, se genera una alerta. + +## Caso de Fallo Detectado + +A continuación se describe el escenario que esta política detectará. + +--- +### Caso Único: Regla de Eventos para Problemas de Cloud Guard Ausente o Mal Configurada + +* **Descripción:** Esta regla se activa si en toda la configuración del proyecto no se encuentra ningún recurso `oci_events_rule` habilitado que capture el evento de Cloud Guard. Esto incluye casos donde la regla no existe, o existe pero monitoriza eventos diferentes. +* **Ubicación de la Alerta:** La alerta se anclará al bloque `provider "oci" {}`, indicando que falta una configuración global de seguridad. + +* **Ejemplo de Código Terraform Problemático:** + ```terraform + # El proyecto puede tener otras reglas de eventos, pero ninguna para + # notificar los problemas detectados por Cloud Guard. + + resource "oci_events_rule" "example_rule_wrong_event" { + display_name = "rule-for-instance-events" + compartment_id = var.compartment_id + is_enabled = true + + # FALLO: Esta condición monitoriza el lanzamiento de instancias, + # pero ignora los problemas de seguridad de Cloud Guard. + condition = "{\"eventType\":[\"com.oraclecloud.compute.instance.launch.end\"]}" + + actions { + actions { + action_type = "ONS" + topic_id = oci_ons_notification_topic.test_topic.id + } + } + } + ``` + +## Recurso Involucrado + +* `oci_events_rule` + +## Solución + +Para solucionar el problema detectado, asegúrate de que tu configuración de Terraform incluya al menos un recurso `oci_events_rule` habilitado y configurado específicamente para el evento de problema de Cloud Guard. + +Se recomienda filtrar por niveles de riesgo (CRITICAL, HIGH) para evitar ruido, como se muestra a continuación: + +```terraform +# RECURSO REQUERIDO PARA LA SOLUCIÓN +resource "oci_events_rule" "cloud_guard_problem_rule" { + display_name = "notify-on-cloud-guard-problems" + description = "Sends a notification when Cloud Guard detects a new problem" + compartment_id = var.tenancy_ocid + is_enabled = true + + # La condición busca el evento específico y filtra por severidad. + condition = jsonencode({ + eventType = [ + "com.oraclecloud.cloudguard.problem" + ], + data = { + "riskLevel" = [ + "CRITICAL", + "HIGH" + ] + } + }) + + actions { + actions { + action_type = "ONS" + topic_id = oci_ons_notification_topic.security_alerts_topic.id + } + } +} + +# Recurso auxiliar: Tópico de notificación para enviar la alerta. +resource "oci_ons_notification_topic" "security_alerts_topic" { + compartment_id = var.compartment_id + name = "security-alerts-topic" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json new file mode 100644 index 00000000000..30679dbec92 --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "3ce366ab-e97d-4040-aa67-5a08dad595fb", + "queryName": "Event Rule for Cloud Guard Problems is Missing", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that an OCI event rule is configured to create notifications for problems detected by Cloud Guard. Without a notification rule, critical security findings from Cloud Guard may go unnoticed, delaying response to potential threats.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "3ce366ab", + "cloudProvider": "oci", + "cwe": "CWE-778", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/query.rego new file mode 100644 index 00000000000..242b379619d --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/query.rego @@ -0,0 +1,24 @@ +package Cx + +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + expected_event_type := "com.oraclecloud.cloudguard.problem" + + rules_with_correct_event := [rule | + rule := input.document[_].resource.oci_events_rule[_] + rule.is_enabled == true + contains(rule.condition, expected_event_type) + ] + + count(rules_with_correct_event) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for Cloud Guard problems should exist in the project", + "keyActualValue": "No 'oci_events_rule' is configured to audit Cloud Guard problems", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/negative1.tf b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/negative1.tf new file mode 100644 index 00000000000..b418e886130 --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/negative1.tf @@ -0,0 +1,17 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "cg_correct" { + display_name = "CloudGuardCorrect" + is_enabled = true + condition = "{\"eventType\":[\"com.oraclecloud.cloudguard.problem\"]}" + + actions { + actions { + action_type = "ONS" + is_enabled = true + topic_id = "ocid1.onstopic..." + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive1.tf b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive1.tf new file mode 100644 index 00000000000..3a0b3bccec0 --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive1.tf @@ -0,0 +1,9 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_instance" "example" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive2.tf new file mode 100644 index 00000000000..b0c092d9f6c --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive2.tf @@ -0,0 +1,17 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "cg_disabled" { + display_name = "CloudGuardDisabled" + is_enabled = false + condition = "{\"eventType\":[\"com.oraclecloud.cloudguard.problem\"]}" + + actions { + actions { + action_type = "ONS" + is_enabled = true + topic_id = "ocid1.onstopic..." + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive3.tf b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive3.tf new file mode 100644 index 00000000000..99de9217c22 --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive3.tf @@ -0,0 +1,17 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "bucket_event" { + display_name = "BucketEvent" + is_enabled = true + condition = "{\"eventType\":[\"com.oraclecloud.objectstorage.createbucket\"]}" + + actions { + actions { + action_type = "ONS" + is_enabled = true + topic_id = "ocid1.onstopic..." + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..0c87e86299f --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Event Rule for Cloud Guard Problems is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Event Rule for Cloud Guard Problems is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive2.tf" + }, + { + "queryName": "Event Rule for Cloud Guard Problems is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/README.md b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/README.md new file mode 100644 index 00000000000..b9a7f33354c --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/README.md @@ -0,0 +1,76 @@ +# Regla KICS: Cloud Guard Habilitado en el Compartimento Raíz de OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que el servicio OCI Cloud Guard esté habilitado (`status = "ENABLED"`) y configurado para operar a nivel del compartimento raíz (*tenancy*). + +Cloud Guard es el servicio de gestión de la postura de seguridad (CSPM) nativo de OCI. Proporciona una visión centralizada de la seguridad, detecta configuraciones incorrectas y actividades anómalas, y puede automatizar la respuesta a problemas. Para obtener la máxima visibilidad y protección, IBM y Oracle recomiendan activarlo en el compartimento raíz, ya que sus políticas se heredan a todos los compartimentos hijos. + +## Lógica de la Regla + +La política se divide en tres reglas para cubrir todos los escenarios de mala configuración: +1. El recurso `oci_cloud_guard_configuration` no existe. +2. El recurso existe, pero su `status` no es `ENABLED`. +3. El recurso existe y está habilitado, pero no está asignado al compartimento raíz. + +## Casos de Fallo Detectados + +A continuación se describen los tres escenarios que esta política detectará. + +--- +### Caso 1: Recurso `oci_cloud_guard_configuration` Ausente + +* **Descripción:** Esta regla se activa si no existe ningún recurso `oci_cloud_guard_configuration` en toda la configuración, lo que significa que Cloud Guard no está siendo gestionado por Terraform. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + # El proyecto no define ninguna configuración para Cloud Guard. + ``` +* **Ubicación de la Alerta:** La alerta se anclará al bloque `provider "oci" {}`. + +--- +### Caso 2: `status` de Cloud Guard no es `ENABLED` + +* **Descripción:** Esta regla detecta un recurso `oci_cloud_guard_configuration` que existe, pero cuyo `status` es diferente de `"ENABLED"` (por ejemplo, `"DISABLED"`). +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "oci_cloud_guard_configuration" "cg_config_disabled" { + compartment_id = var.tenancy_ocid + reporting_region = "us-ashburn-1" + status = "DISABLED" # <-- ¡PROBLEMA! + } + ``` +* **Ubicación de la Alerta:** La alerta señalará directamente a la línea `status = "DISABLED"`. + +--- +### Caso 3: Cloud Guard no está en el Compartimento Raíz + +* **Descripción:** Esta regla detecta un recurso `oci_cloud_guard_configuration` que está habilitado (`status = "ENABLED"`), pero su `compartment_id` no es el del *tenancy* (raíz). La regla identifica esto de forma heurística, comprobando que el OCID del compartimento no contenga la palabra `tenancy`. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "oci_cloud_guard_configuration" "cg_config_wrong_compartment" { + # Apunta a un compartimento hijo en lugar del raíz. + compartment_id = var.child_compartment_ocid # <-- ¡PROBLEMA! + + reporting_region = "us-ashburn-1" + status = "ENABLED" + } + ``` +* **Ubicación de la Alerta:** La alerta señalará directamente a la línea `compartment_id`. + +## Recurso Involucrado + +* `oci_cloud_guard_configuration` + +## Solución + +Para solucionar los problemas detectados, asegúrate de que exista un único recurso `oci_cloud_guard_configuration` con el `status` en `"ENABLED"` y el `compartment_id` apuntando al OCID del *tenancy* (compartimento raíz). + +```terraform +resource "oci_cloud_guard_configuration" "cg_config_correct" { + # El compartment_id debe ser el del tenancy para una cobertura completa. + compartment_id = var.tenancy_ocid + + reporting_region = "us-ashburn-1" + status = "ENABLED" +} +``` \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json new file mode 100644 index 00000000000..2fe76f5d26d --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "3e784705-b3c6-4197-9a04-0b751b1a83d8", + "queryName": "Cloud Guard Not Enabled at Root Compartment", + "severity": "HIGH", + "category": "Security Services", + "descriptionText": "Ensures that OCI Cloud Guard is enabled at the tenancy's root compartment. Cloud Guard is a cloud-native security posture management service that helps monitor, identify, and maintain a strong security posture on Oracle Cloud.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/cloud_guard_configuration", + "platform": "Terraform", + "descriptionID": "3e784705", + "cloudProvider": "oci", + "cwe": "CWE-16", + "riskScore": 6.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego new file mode 100644 index 00000000000..50852570508 --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego @@ -0,0 +1,52 @@ +package Cx + +# REGLA 1: No existe ningún recurso 'oci_cloud_guard_configuration'. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + all_cloud_guards := [cg | + cg := input.document[_].resource.oci_cloud_guard_configuration[_] + ] + + count(all_cloud_guards) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "Resource 'oci_cloud_guard_configuration' should exist to enable Cloud Guard", + "keyActualValue": "Resource 'oci_cloud_guard_configuration' is missing", + } +} + +# REGLA 2: Cloud Guard existe, pero su 'status' no es 'ENABLED'. +CxPolicy[result] { + cg := input.document[i].resource.oci_cloud_guard_configuration[cg_name] + + cg.status != "ENABLED" + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_cloud_guard_configuration.%s.status", [cg_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'status' attribute should be 'ENABLED'", + "keyActualValue": sprintf("'status' attribute is '%s'", [cg.status]), + } +} + +# REGLA 3: Cloud Guard existe y está habilitado, pero no en el compartimento raíz. +CxPolicy[result] { + cg := input.document[i].resource.oci_cloud_guard_configuration[cg_name] + + cg.status == "ENABLED" + not contains(lower(cg.compartment_id), "tenancy") + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_cloud_guard_configuration.%s.compartment_id", [cg_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'compartment_id' should be the tenancy (root compartment) OCID", + "keyActualValue": "'compartment_id' is not the tenancy OCID", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/negative1.tf b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/negative1.tf new file mode 100644 index 00000000000..062b0c647e3 --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/negative1.tf @@ -0,0 +1,10 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_cloud_guard_configuration" "cg_correct" { + # CORRECTO: Contiene la palabra "tenancy" + compartment_id = var.tenancy_ocid + reporting_region = "us-ashburn-1" + status = "ENABLED" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive1.tf b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive1.tf new file mode 100644 index 00000000000..f4602b1ed95 --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive1.tf @@ -0,0 +1,9 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_compartment" "example" { + compartment_id = "ocid1.tenancy..." + name = "example_compartment" + description = "Just a compartment" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive2.tf b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive2.tf new file mode 100644 index 00000000000..94e15af8b95 --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive2.tf @@ -0,0 +1,9 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_cloud_guard_configuration" "cg_disabled" { + compartment_id = var.tenancy_ocid + reporting_region = "us-ashburn-1" + status = "DISABLED" # FALLO +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive3.tf b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive3.tf new file mode 100644 index 00000000000..ee69e810d6b --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive3.tf @@ -0,0 +1,10 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_cloud_guard_configuration" "cg_child" { + # FALLO: Apunta a un compartimento hijo, no al tenancy + compartment_id = var.child_compartment_id + reporting_region = "us-ashburn-1" + status = "ENABLED" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..6aa60561436 --- /dev/null +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Cloud Guard Not Enabled at Root Compartment", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Cloud Guard Not Enabled at Root Compartment", + "severity": "HIGH", + "line": 8, + "fileName": "positive2.tf" + }, + { + "queryName": "Cloud Guard Not Enabled at Root Compartment", + "severity": "HIGH", + "line": 7, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/README.md b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/README.md new file mode 100644 index 00000000000..1755079010f --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/README.md @@ -0,0 +1,71 @@ +# Regla KICS: Endpoints de Metadatos Legacy Deshabilitados en Instancias de OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que todas las instancias de cómputo de OCI (`oci_core_instance`) tengan los endpoints del servicio de metadatos legacy (IMDSv1) deshabilitados. + +El servicio de metadatos de instancia (IMDS) permite a una instancia obtener información sobre sí misma. La versión 1 (legacy) es vulnerable a ataques de tipo SSRF (Server-Side Request Forgery). La versión 2 (IMDSv2) introduce protecciones que mitigan este riesgo. Deshabilitar los endpoints legacy y forzar el uso de IMDSv2 es una práctica de seguridad fundamental para proteger las instancias. + +## Lógica de la Regla + +La política verifica la presencia y configuración del atributo `are_legacy_imds_endpoints_disabled` dentro del bloque `agent_config`. + +## Casos de Fallo Detectados + +A continuación se describen los tres escenarios que esta política detectará. + +--- +### Caso 1: Bloque `agent_config` Ausente + +* **Descripción:** El recurso `oci_core_instance` no define el bloque `agent_config`. Por defecto, esto implica que la configuración de seguridad no está aplicada. +* **Ejemplo:** + ```terraform + resource "oci_core_instance" "test" { + # Falta el bloque agent_config + } + ``` +* **Ubicación de la Alerta:** Bloque del recurso `oci_core_instance`. + +--- +### Caso 2: Atributo Ausente en `agent_config` + +* **Descripción:** El bloque `agent_config` existe, pero no contiene el atributo `are_legacy_imds_endpoints_disabled`. El valor por defecto es `false` (inseguro). +* **Ejemplo:** + ```terraform + resource "oci_core_instance" "test" { + agent_config { + # Falta el atributo are_legacy_imds_endpoints_disabled + is_monitoring_disabled = false + } + } + ``` +* **Ubicación de la Alerta:** Bloque `agent_config`. + +--- +### Caso 3: Atributo Configurado como `false` + +* **Descripción:** El atributo `are_legacy_imds_endpoints_disabled` está presente pero explícitamente configurado como `false`, habilitando los endpoints legacy inseguros. +* **Ejemplo:** + ```terraform + resource "oci_core_instance" "test" { + agent_config { + are_legacy_imds_endpoints_disabled = false # <-- ¡PROBLEMA! + } + } + ``` +* **Ubicación de la Alerta:** Línea del atributo `are_legacy_imds_endpoints_disabled`. + +## Recurso Involucrado + +* `oci_core_instance` + +## Solución + +```terraform +resource "oci_core_instance" "test_instance_correct" { + # ... otros atributos ... + + agent_config { + are_legacy_imds_endpoints_disabled = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json new file mode 100644 index 00000000000..096fbcb75b1 --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "96b464dc-a778-4b99-8634-c9eb9bdecf89", + "queryName": "Compute Instance Legacy Metadata Enabled", + "severity": "MEDIUM", + "category": "Insecure Configurations", + "descriptionText": "Ensures that OCI Compute Instances have legacy metadata service endpoints (IMDSv1) disabled. Enforcing the use of IMDSv2 is a security best practice to mitigate Server-Side Request Forgery (SSRF) vulnerabilities.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_instance#are_legacy_imds_endpoints_disabled", + "platform": "Terraform", + "descriptionID": "96b464dc", + "cloudProvider": "oci", + "cwe": "CWE-918", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/query.rego b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/query.rego new file mode 100644 index 00000000000..6810f9c2967 --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/query.rego @@ -0,0 +1,48 @@ +package Cx + +# REGLA 1: Falta el bloque 'agent_config' por completo. +CxPolicy[result] { + instance := input.document[i].resource.oci_core_instance[instance_name] + + not instance.agent_config + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_core_instance.%s", [instance_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'agent_config' block should be defined", + "keyActualValue": "'agent_config' block is missing", + } +} + +# REGLA 2: Existe 'agent_config', pero falta el atributo dentro. +CxPolicy[result] { + instance := input.document[i].resource.oci_core_instance[instance_name] + agent_config := instance.agent_config + + object.get(agent_config, "are_legacy_imds_endpoints_disabled", null) == null + + result := { + "documentId": input.document[i].id, + # AQUI ESTA EL CAMBIO: Apuntamos al bloque agent_config + "searchKey": sprintf("resource.oci_core_instance.%s.agent_config", [instance_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'are_legacy_imds_endpoints_disabled' should be present and set to 'true'", + "keyActualValue": "'are_legacy_imds_endpoints_disabled' is missing inside 'agent_config'", + } +} + +# REGLA 3: El atributo existe pero es 'false'. +CxPolicy[result] { + instance := input.document[i].resource.oci_core_instance[instance_name] + + instance.agent_config.are_legacy_imds_endpoints_disabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_core_instance.%s.agent_config.are_legacy_imds_endpoints_disabled", [instance_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'are_legacy_imds_endpoints_disabled' attribute should be 'true'", + "keyActualValue": "'are_legacy_imds_endpoints_disabled' attribute is 'false'", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/negative1.tf b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/negative1.tf new file mode 100644 index 00000000000..548be50c429 --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/negative1.tf @@ -0,0 +1,10 @@ +resource "oci_core_instance" "negative1" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + + agent_config { + # CORRECTO + are_legacy_imds_endpoints_disabled = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive1.tf b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive1.tf new file mode 100644 index 00000000000..0eb1571db93 --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive1.tf @@ -0,0 +1,6 @@ +resource "oci_core_instance" "positive1" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + # FALLO: Falta agent_config (Caso 1) +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive2.tf b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive2.tf new file mode 100644 index 00000000000..2cbe5ac1ad0 --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive2.tf @@ -0,0 +1,10 @@ +resource "oci_core_instance" "positive2" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + + agent_config { + # FALLO: Falta atributo (Caso 2) + is_monitoring_disabled = false + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive3.tf b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive3.tf new file mode 100644 index 00000000000..e1e52522238 --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive3.tf @@ -0,0 +1,10 @@ +resource "oci_core_instance" "positive3" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + + agent_config { + # FALLO: Valor incorrecto (Caso 3) + are_legacy_imds_endpoints_disabled = false + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive_expected_result.json new file mode 100644 index 00000000000..5ec1f031f8e --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Compute Instance Legacy Metadata Enabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Compute Instance Legacy Metadata Enabled", + "severity": "MEDIUM", + "line": 6, + "fileName": "positive2.tf" + }, + { + "queryName": "Compute Instance Legacy Metadata Enabled", + "severity": "MEDIUM", + "line": 8, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/README.md b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/README.md new file mode 100644 index 00000000000..5ed4f78d123 --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/README.md @@ -0,0 +1,73 @@ +# Regla KICS: Secure Boot Habilitado en Instancias de Cómputo de OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que todas las instancias de cómputo de OCI (`oci_core_instance`) que lo soporten tengan la funcionalidad de "Arranque Seguro" (Secure Boot) habilitada. + +Secure Boot es un estándar de seguridad desarrollado por la industria para asegurar que un dispositivo arranque utilizando únicamente software de confianza del fabricante del equipo original (OEM). Cuando el PC arranca, el firmware comprueba la firma de cada pieza de software de arranque, incluido el sistema operativo. Si las firmas son válidas, el PC arranca y el firmware cede el control al sistema operativo. Habilitarlo protege contra malware a nivel de arranque como los rootkits. + +## Lógica de la Regla + +La política verifica la presencia y configuración del atributo `is_secure_boot_enabled` dentro del bloque `shape_config`. + +## Casos de Fallo Detectados + +A continuación se describen los tres escenarios que esta política detectará. + +--- +### Caso 1: Bloque `shape_config` Ausente + +* **Descripción:** El recurso `oci_core_instance` no define el bloque `shape_config`. Por defecto, esto implica que Secure Boot está deshabilitado. +* **Ejemplo:** + ```terraform + resource "oci_core_instance" "test" { + # Falta el bloque shape_config + } + ``` +* **Ubicación de la Alerta:** Bloque del recurso `oci_core_instance`. + +--- +### Caso 2: Atributo Ausente en `shape_config` + +* **Descripción:** El bloque `shape_config` existe, pero no contiene el atributo `is_secure_boot_enabled`. El valor por defecto es `false`. +* **Ejemplo:** + ```terraform + resource "oci_core_instance" "test" { + shape_config { + # Falta is_secure_boot_enabled + ocpus = 1 + } + } + ``` +* **Ubicación de la Alerta:** Bloque `shape_config`. + +--- +### Caso 3: Atributo Configurado como `false` + +* **Descripción:** El atributo `is_secure_boot_enabled` está presente pero explícitamente configurado como `false`. +* **Ejemplo:** + ```terraform + resource "oci_core_instance" "test" { + shape_config { + is_secure_boot_enabled = false # <-- ¡PROBLEMA! + } + } + ``` +* **Ubicación de la Alerta:** Línea del atributo `is_secure_boot_enabled`. + +## Recurso Involucrado + +* `oci_core_instance` + +## Solución + +Para solucionar los problemas detectados, asegúrate de que cada recurso `oci_core_instance` incluya un bloque `shape_config` con el atributo `is_secure_boot_enabled` configurado en `true`. + +```terraform +resource "oci_core_instance" "test_instance_correct" { + # ... otros atributos ... + + shape_config { + is_secure_boot_enabled = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json new file mode 100644 index 00000000000..cf5f14dbb12 --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "1f24d72d-c8be-403f-92b8-84ed910fe96e", + "queryName": "Compute Instance Secure Boot Disabled", + "severity": "MEDIUM", + "category": "Insecure Configurations", + "descriptionText": "Ensures that OCI Compute Instances have Secure Boot enabled. Secure Boot is a feature of UEFI firmware that helps prevent unauthorized boot loaders and operating systems from loading during the startup process, protecting against rootkits and boot-level malware.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_instance#is_secure_boot_enabled", + "platform": "Terraform", + "descriptionID": "1f24d72d", + "cloudProvider": "oci", + "cwe": "CWE-427", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego new file mode 100644 index 00000000000..1f132489d88 --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego @@ -0,0 +1,48 @@ +package Cx + +# REGLA 1: Falta el bloque 'shape_config' por completo. +CxPolicy[result] { + instance := input.document[i].resource.oci_core_instance[instance_name] + + not instance.shape_config + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_core_instance.%s", [instance_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'shape_config' block should be defined", + "keyActualValue": "'shape_config' block is missing", + } +} + +# REGLA 2: Existe 'shape_config', pero falta el atributo dentro. +CxPolicy[result] { + instance := input.document[i].resource.oci_core_instance[instance_name] + shape_config := instance.shape_config + + object.get(shape_config, "is_secure_boot_enabled", null) == null + + result := { + "documentId": input.document[i].id, + # Apuntamos al bloque shape_config + "searchKey": sprintf("resource.oci_core_instance.%s.shape_config", [instance_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'is_secure_boot_enabled' should be present inside 'shape_config' and set to 'true'", + "keyActualValue": "'is_secure_boot_enabled' is missing inside 'shape_config'", + } +} + +# REGLA 3: El atributo existe pero es 'false'. +CxPolicy[result] { + instance := input.document[i].resource.oci_core_instance[instance_name] + + instance.shape_config.is_secure_boot_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_core_instance.%s.shape_config.is_secure_boot_enabled", [instance_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_secure_boot_enabled' attribute should be 'true'", + "keyActualValue": "'is_secure_boot_enabled' attribute is 'false'", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/negative1.tf b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/negative1.tf new file mode 100644 index 00000000000..744a095c1e3 --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/negative1.tf @@ -0,0 +1,10 @@ +resource "oci_core_instance" "negative1" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + + shape_config { + # CORRECTO + is_secure_boot_enabled = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive1.tf b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive1.tf new file mode 100644 index 00000000000..e13edbd871a --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive1.tf @@ -0,0 +1,6 @@ +resource "oci_core_instance" "positive1" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + # FALLO: Falta shape_config (Caso 1) +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive2.tf b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive2.tf new file mode 100644 index 00000000000..d2385663e68 --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive2.tf @@ -0,0 +1,10 @@ +resource "oci_core_instance" "positive2" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + + shape_config { + # FALLO: Falta is_secure_boot_enabled (Caso 2) + ocpus = 1 + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive3.tf b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive3.tf new file mode 100644 index 00000000000..b16528bffe7 --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive3.tf @@ -0,0 +1,10 @@ +resource "oci_core_instance" "positive3" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + + shape_config { + # FALLO: Configurado a false (Caso 3) + is_secure_boot_enabled = false + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..27215cd5562 --- /dev/null +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Compute Instance Secure Boot Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Compute Instance Secure Boot Disabled", + "severity": "MEDIUM", + "line": 6, + "fileName": "positive2.tf" + }, + { + "queryName": "Compute Instance Secure Boot Disabled", + "severity": "MEDIUM", + "line": 8, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_default_tags_not_defined/README.md b/assets/queries/terraform/oci/oci_default_tags_not_defined/README.md new file mode 100644 index 00000000000..5d457d791fe --- /dev/null +++ b/assets/queries/terraform/oci/oci_default_tags_not_defined/README.md @@ -0,0 +1,69 @@ +# Regla KICS: Tags por Defecto Definidos en OCI + +## Descripción General + +Esta regla de KICS para Terraform verifica que se haya definido una política de etiquetado por defecto en la configuración de OCI. La gestión de esta política se realiza a través del recurso `oci_identity_tag_default`. + +El uso de tags por defecto es una práctica de gobernanza fundamental en la nube. Permite asegurar que todos los recursos creados dentro de un compartimento específico reciban automáticamente un conjunto predefinido de etiquetas. Esto es esencial para la gestión de costes, la automatización de procesos, el control de acceso y la auditoría. + +## Lógica de la Regla + +La política implementa una única regla para verificar la existencia de al menos un recurso `oci_identity_tag_default` en toda la configuración de Terraform. Si no se encuentra ninguno, se asume que no se está gestionando una política de etiquetado por defecto. + +## Caso de Fallo Detectado + +A continuación se describe el escenario que esta política detectará. + +--- +### Caso Único: Recurso `oci_identity_tag_default` Ausente + +* **Descripción:** Esta regla se activa si en toda la configuración de Terraform no se encuentra ni un solo recurso de tipo `oci_identity_tag_default`. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + # El proyecto contiene varios recursos de OCI, pero ninguno define + # una política de tags por defecto. + + resource "oci_core_vcn" "example_vcn" { + compartment_id = var.compartment_id + # ... + } + ``` +* **Ubicación de la Alerta:** La alerta será general y se anclará al bloque `provider "oci" {}` para indicar que falta un recurso `oci_identity_tag_default` en la configuración global. + +## Recurso Involucrado + +* `oci_identity_tag_default` + +## Solución + +Para solucionar el problema detectado, asegúrate de que tu configuración de Terraform incluya al menos un recurso `oci_identity_tag_default`. Este recurso requiere que primero se defina un `oci_identity_tag_namespace` y un `oci_identity_tag`. + +```terraform +# Es necesario definir un espacio de nombres para los tags. +resource "oci_identity_tag_namespace" "example_ns" { + compartment_id = var.compartment_id + description = "Namespace for default tags" + name = "example-namespace" +} + +# Es necesario definir el tag que se usará por defecto. +resource "oci_identity_tag" "example_tag" { + tag_namespace_id = oci_identity_tag_namespace.example_ns.id + description = "Tag for cost center" + name = "CostCenter" +} + +# RECURSO REQUERIDO PARA LA SOLUCIÓN +resource "oci_identity_tag_default" "example_default_tag" { + compartment_id = var.compartment_id + + # ID del tag que se aplicará por defecto. + tag_definition_id = oci_identity_tag.example_tag.id + + # Valor que se aplicará por defecto. + value = "IT-DEPT-123" + + # Asegura que los usuarios no puedan sobreescribir este valor por defecto. + is_required = true +} +``` \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json b/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json new file mode 100644 index 00000000000..6fc5306fe52 --- /dev/null +++ b/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "4c294256-f477-41d5-8c7f-f31c9e48092e", + "queryName": "Default Tags Not Defined", + "severity": "LOW", + "category": "Best Practices", + "descriptionText": "Ensures that a default tagging policy is defined using the 'oci_identity_tag_default' resource. Default tags are crucial for governance as they ensure all resources within a compartment are automatically tagged for cost tracking, automation, and access control.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/identity_tag_default", + "platform": "Terraform", + "descriptionID": "4c294256", + "cloudProvider": "oci", + "cwe": "CWE-16", + "riskScore": 1.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_default_tags_not_defined/query.rego b/assets/queries/terraform/oci/oci_default_tags_not_defined/query.rego new file mode 100644 index 00000000000..7d02815c15c --- /dev/null +++ b/assets/queries/terraform/oci/oci_default_tags_not_defined/query.rego @@ -0,0 +1,20 @@ +package Cx + +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + all_default_tags := [tag | + tag := input.document[_].resource.oci_identity_tag_default[_] + ] + + count(all_default_tags) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "At least one 'oci_identity_tag_default' resource should exist to define a default tagging policy", + "keyActualValue": "No 'oci_identity_tag_default' resource was found in the configuration", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_default_tags_not_defined/test/negative1.tf b/assets/queries/terraform/oci/oci_default_tags_not_defined/test/negative1.tf new file mode 100644 index 00000000000..4962573eb83 --- /dev/null +++ b/assets/queries/terraform/oci/oci_default_tags_not_defined/test/negative1.tf @@ -0,0 +1,22 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_tag_namespace" "example_ns" { + compartment_id = "ocid1.compartment..." + description = "Namespace" + name = "example-namespace" +} + +resource "oci_identity_tag" "example_tag" { + tag_namespace_id = oci_identity_tag_namespace.example_ns.id + description = "Tag" + name = "CostCenter" +} + +resource "oci_identity_tag_default" "example_default_tag" { + compartment_id = "ocid1.compartment..." + tag_definition_id = oci_identity_tag.example_tag.id + value = "IT-DEPT-123" + is_required = true +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_default_tags_not_defined/test/positive1.tf b/assets/queries/terraform/oci/oci_default_tags_not_defined/test/positive1.tf new file mode 100644 index 00000000000..df88a71ceed --- /dev/null +++ b/assets/queries/terraform/oci/oci_default_tags_not_defined/test/positive1.tf @@ -0,0 +1,8 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_vcn" "simple_vcn" { + compartment_id = "ocid1.compartment..." + cidr_block = "10.0.0.0/16" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_default_tags_not_defined/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_default_tags_not_defined/test/positive_expected_result.json new file mode 100644 index 00000000000..cba73e9f9be --- /dev/null +++ b/assets/queries/terraform/oci/oci_default_tags_not_defined/test/positive_expected_result.json @@ -0,0 +1,8 @@ +[ + { + "queryName": "Default Tags Not Defined", + "severity": "LOW", + "line": 1, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/README.md new file mode 100644 index 00000000000..76f87609c67 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/README.md @@ -0,0 +1,122 @@ +# Regla KICS: Notificación para Cambios en Grupos de IAM en OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio (creación, actualización o eliminación) en los grupos de IAM de la cuenta de OCI. + +Los grupos de IAM son la base de la gestión de permisos en OCI. Un atacante o un actor interno malicioso podría crear un nuevo grupo con altos privilegios, añadir usuarios a un grupo de administradores, o eliminar un grupo existente para causar una denegación de servicio. Monitorizar estos cambios en tiempo real es una medida de seguridad esencial para detectar escaladas de privilegios no autorizadas o manipulaciones en los controles de acceso. + +## Lógica de la Regla + +La política realiza un análisis exhaustivo en busca de reglas que capturen los siguientes tres tipos de eventos críticos de IAM: +1. `com.oraclecloud.identity.creategroup` +2. `com.oraclecloud.identity.updategroup` +3. `com.oraclecloud.identity.deletegroup` + +La validación se divide en tres comprobaciones específicas: +1. **Existencia Global:** Verifica si existe al menos una regla en todo el proyecto que monitorice eventos de grupos IAM. +2. **Integridad de la Condición:** Si la regla existe, verifica que incluya **los tres** tipos de eventos mencionados anteriormente. +3. **Estado de la Regla:** Verifica que la regla, si está correctamente configurada, se encuentre habilitada (`is_enabled = true`). + +## Casos de Fallo Detectados + +A continuación se describen los tres escenarios específicos que esta política detectará. + +--- +### Caso 1: Regla de Eventos para Grupos IAM Totalmente Ausente + +* **Descripción:** Esta regla se activa si en toda la configuración de Terraform no se encuentra ningún recurso `oci_events_rule` que haga referencia a eventos de grupos de IAM. Esto indica una falta total de auditoría sobre estos recursos. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + # El proyecto define recursos de infraestructura, pero carece de reglas de + # eventos para seguridad de IAM. + + provider "oci" { + region = "us-ashburn-1" + } + ``` +* **Ubicación de la Alerta:** La alerta será general y se anclará al bloque `provider "oci" {}`. + +--- +### Caso 2: Regla de Eventos Incompleta (Faltan Tipos de Eventos) + +* **Descripción:** Se ha detectado una regla `oci_events_rule` destinada a monitorizar grupos, pero su configuración es incompleta. La propiedad `condition` incluye algunos eventos (por ejemplo, solo la creación), pero omite otros críticos (como la eliminación o actualización). +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "oci_events_rule" "iam_group_partial" { + display_name = "audit-iam-create" + is_enabled = true + + # FALLO: Solo monitoriza la creación, ignorando actualizaciones y borrados. + condition = jsonencode({ + "eventType": ["com.oraclecloud.identity.creategroup"] + }) + + actions { + # ... configuración de acciones ... + } + } + ``` +* **Ubicación de la Alerta:** La alerta señalará específicamente al atributo `condition` dentro del recurso `oci_events_rule` afectado. + +--- +### Caso 3: Regla de Eventos Deshabilitada + +* **Descripción:** Existe una regla `oci_events_rule` correctamente configurada que incluye todos los eventos de grupos de IAM necesarios, pero se encuentra explícitamente deshabilitada (`is_enabled = false`), por lo que no está protegiendo el entorno. +* **Ejemplo de Código Terraform Problemático:** + ```terraform + resource "oci_events_rule" "iam_group_disabled" { + display_name = "audit-iam-all" + + # FALLO: La regla está bien definida pero apagada. + is_enabled = false + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identity.creategroup", + "com.oraclecloud.identity.updategroup", + "com.oraclecloud.identity.deletegroup" + ] + }) + } + ``` +* **Ubicación de la Alerta:** La alerta señalará al atributo `is_enabled` dentro del recurso. + +## Recurso Involucrado + +* `oci_events_rule` + +## Solución + +Para solucionar cualquiera de los problemas detectados, asegúrate de configurar un recurso `oci_events_rule` que incluya los tres eventos requeridos y esté habilitado. + +```terraform +# RECURSO REQUERIDO PARA LA SOLUCIÓN +resource "oci_events_rule" "iam_group_change_rule" { + display_name = "audit-rule-for-iam-group-changes" + description = "Alerts on any creation, update, or deletion of IAM groups" + compartment_id = var.tenancy_ocid # Los eventos de IAM suelen ser a nivel de Tenancy + is_enabled = true + + # La condición debe incluir explícitamente los tres tipos de eventos. + condition = jsonencode({ + eventType = [ + "com.oraclecloud.identity.creategroup", + "com.oraclecloud.identity.updategroup", + "com.oraclecloud.identity.deletegroup" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = oci_ons_notification_topic.security_alerts_topic.id + } + } +} + +# Recurso auxiliar: Tópico de notificación para enviar la alerta. +resource "oci_ons_notification_topic" "security_alerts_topic" { + compartment_id = var.compartment_id + name = "security-alerts-topic" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json new file mode 100644 index 00000000000..3e1725b4d05 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "3f6ba6dd-fa6d-45b4-8b27-120b7ebb4d0f", + "queryName": "Event Rule for IAM Group Changes is Missing", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to IAM groups. Auditing the creation, modification, and deletion of user groups is a critical security measure to detect unauthorized privilege escalation or tampering with access controls.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "3f6ba6dd", + "cloudProvider": "oci", + "cwe": "CWE-778", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego new file mode 100644 index 00000000000..d8e3f3902f3 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego @@ -0,0 +1,77 @@ +package Cx + +expected_event_types := [ + "com.oraclecloud.identity.creategroup", + "com.oraclecloud.identity.updategroup", + "com.oraclecloud.identity.deletegroup" +] + +# REGLA 1: Missing (Global) +# No existe NINGUNA regla en el proyecto que monitoree eventos de IAM (ni siquiera parcialmente). +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_iam_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_iam_rule) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for IAM group changes should exist", + "keyActualValue": "No 'oci_events_rule' found for IAM group changes", + } +} + +# REGLA 2: Incomplete (Local) +# La regla existe y mira eventos de IAM, pero le falta alguno de los 3 requeridos. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 3 IAM group events (create, update, delete)", + "keyActualValue": sprintf("The rule is missing %d IAM group event(s)", [missing_count]), + } +} + +# REGLA 3: Disabled (Local) +# La regla tiene todos los eventos correctos, pero está deshabilitada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) == count(expected_event_types) + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/negative1.tf b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/negative1.tf new file mode 100644 index 00000000000..3c72c48f58f --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/negative1.tf @@ -0,0 +1,23 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "iam_group_changes" { + display_name = "IAMGroupChanges" + is_enabled = true + + condition = < **Fallo**. + * Si el atributo no está definido -> **Fallo** (se asume configuración insegura/desconocida). + +2. **Para IAM Clásico (`oci_identity_authentication_policy`):** + * Genera siempre una alerta **Manual (INFO)**, indicando al auditor que debe verificar la consola de OCI. + +## Casos de Fallo Detectados + +### Caso 1: Expiración Excesiva (Identity Domains) +* **Descripción:** La política define `password_expires_after` con un valor mayor a 365 días. +* **Ubicación:** Atributo `password_expires_after`. + +### Caso 2: Atributo Faltante (Identity Domains) +* **Descripción:** Falta el atributo `password_expires_after`. +* **Ubicación:** Recurso `oci_identity_domains_password_policy`. + +### Caso 3: Recurso Legacy (Manual Check) +* **Descripción:** Se utiliza `oci_identity_authentication_policy`. +* **Ubicación:** Recurso `oci_identity_authentication_policy`. + +## Solución + +Para **Identity Domains**, establece la caducidad en 365 días o menos. + +```terraform +resource "oci_identity_domains_password_policy" "secure_policy" { + # ... otros atributos ... + idcs_endpoint = var.idcs_endpoint + + # Caducidad de contraseña en 90 días (Recomendado) + password_expires_after = 90 + + schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/metadata.json b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/metadata.json new file mode 100644 index 00000000000..448d734df94 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "7f47496b-8cdc-4476-9161-6c58038ef920", + "queryName": "OCI IAM Password Expiration (365 days)", + "severity": "INFO", + "category": "Identity and Access Management", + "descriptionText": "CIS Benchmark recommends that passwords expire within 365 days. Verify 'password_expires_after' is set to 365 or less in 'oci_identity_domains_password_policy'. Legacy policies require manual verification.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/identity_domains_password_policy", + "platform": "Terraform", + "descriptionID": "7f47496b", + "cloudProvider": "oci", + "cwe": "CWE-261", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/query.rego b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/query.rego new file mode 100644 index 00000000000..61245d9ec1e --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/query.rego @@ -0,0 +1,47 @@ +package Cx + +# CASO 1: Identity Domains - Expiración (password_expires_after) > 365. +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.oci_identity_domains_password_policy[name] + + policy.password_expires_after > 365 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_domains_password_policy.%s.password_expires_after", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'password_expires_after' should be <= 365", + "keyActualValue": sprintf("'password_expires_after' is %d", [policy.password_expires_after]), + } +} + +# CASO 2: Identity Domains - Atributo faltante. +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.oci_identity_domains_password_policy[name] + + object.get(policy, "password_expires_after", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_domains_password_policy.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'password_expires_after' should be defined (<= 365)", + "keyActualValue": "'password_expires_after' is missing", + } +} + +# CASO 3: IAM Clásico (Legacy) - Manual. +CxPolicy[result] { + doc := input.document[i] + _ := doc.resource.oci_identity_authentication_policy[name] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_authentication_policy.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "Password expiration should be enforced (<= 365 days)", + "keyActualValue": "Legacy resource does not support password expiration config in Terraform. Manual console check required.", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/negative1.tf b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/negative1.tf new file mode 100644 index 00000000000..bfbf8914113 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/negative1.tf @@ -0,0 +1,7 @@ +resource "oci_identity_domains_password_policy" "correct_policy" { + idcs_endpoint = "https://idcs-..." + name = "CorrectPolicy" + # CORRECTO: <= 365 + password_expires_after = 90 + schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive1.tf b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive1.tf new file mode 100644 index 00000000000..55fbf6400cb --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive1.tf @@ -0,0 +1,7 @@ +resource "oci_identity_domains_password_policy" "long_expiration" { + idcs_endpoint = "https://idcs-..." + name = "LongExpirationPolicy" + # FALLO: > 365 + password_expires_after = 400 + schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive2.tf b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive2.tf new file mode 100644 index 00000000000..2f876028117 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive2.tf @@ -0,0 +1,7 @@ +resource "oci_identity_domains_password_policy" "missing_attr" { + idcs_endpoint = "https://idcs-..." + name = "MissingAttrPolicy" + # FALLO: Falta el atributo + password_min_length = 14 + schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive3.tf b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive3.tf new file mode 100644 index 00000000000..22742fb6d8c --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive3.tf @@ -0,0 +1,7 @@ +resource "oci_identity_authentication_policy" "legacy_policy" { + compartment_id = "ocid1.tenancy..." + # FALLO: Legacy + password_policy { + minimum_password_length = 14 + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..dd9cd8a4534 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "OCI IAM Password Expiration (365 days)", + "severity": "INFO", + "line": 5, + "fileName": "positive1.tf" + }, + { + "queryName": "OCI IAM Password Expiration (365 days)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + }, + { + "queryName": "OCI IAM Password Expiration (365 days)", + "severity": "INFO", + "line": 1, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/README.md b/assets/queries/terraform/oci/oci_iam_password_policy_length/README.md new file mode 100644 index 00000000000..35bfc9531ab --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/README.md @@ -0,0 +1,55 @@ +# Regla KICS: OCI IAM Password Minimum Length + +## Descripción General + +Esta regla automatizada (MEDIUM) audita el recurso `oci_identity_authentication_policy`. + +Para garantizar una protección robusta contra ataques de fuerza bruta, el **CIS Oracle Cloud Infrastructure Benchmark** recomienda establecer la longitud mínima de la contraseña en **14 caracteres** o más. + +El valor predeterminado de OCI (si no se especifica) suele ser de 12 caracteres, lo cual es insuficiente para los estándares actuales. Esta regla alerta si: +1. La longitud se define explícitamente menor a 14. +2. Falta el atributo de longitud (usa default). +3. Falta el bloque de política de contraseñas completo (usa default). + +## Lógica de la Regla + +1. Identifica el recurso `oci_identity_authentication_policy`. +2. Verifica la existencia del bloque `password_policy`. + * Si no existe el bloque -> **Fallo** (se usa configuración insegura por defecto). +3. Si el bloque existe, verifica el atributo `minimum_password_length`: + * Si el atributo falta -> **Fallo** (se usa configuración insegura por defecto). + * Si el atributo es `< 14` -> **Fallo**. + +## Casos de Fallo Detectados + +### Caso 1: Longitud Insuficiente +* **Descripción:** Se ha configurado explícitamente `minimum_password_length` con un valor bajo (ej. 8 o 12). +* **Ubicación de la Alerta:** Atributo `minimum_password_length`. + +### Caso 2: Atributo Faltante +* **Descripción:** El bloque existe, pero falta `minimum_password_length`, aplicando el default del proveedor. +* **Ubicación de la Alerta:** Bloque `password_policy`. + +### Caso 3: Bloque Ausente +* **Descripción:** No se ha definido `password_policy` en absoluto. +* **Ubicación de la Alerta:** Recurso `oci_identity_authentication_policy`. + +## Recurso Involucrado +* `oci_identity_authentication_policy` + +## Solución + +Define el bloque `password_policy` y establece explícitamente la longitud en al menos 14. + +```terraform +resource "oci_identity_authentication_policy" "secure_policy" { + compartment_id = var.tenancy_ocid + + password_policy { + minimum_password_length = 14 + is_lowercase_characters_required = true + is_uppercase_characters_required = true + is_numeric_characters_required = true + is_special_characters_required = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json b/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json new file mode 100644 index 00000000000..df4b0cbef87 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "ef7a0923-a4e6-4aec-921b-1b4e45463fb6", + "queryName": "OCI IAM Password Minimum Length", + "severity": "MEDIUM", + "category": "Identity and Access Management", + "descriptionText": "The IAM password policy allows passwords shorter than 14 characters. According to CIS Benchmarks, the 'minimum_password_length' in 'oci_identity_authentication_policy' should be set to 14 or greater.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/identity_authentication_policy", + "platform": "Terraform", + "descriptionID": "ef7a0923", + "cloudProvider": "oci", + "cwe": "CWE-521", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/query.rego b/assets/queries/terraform/oci/oci_iam_password_policy_length/query.rego new file mode 100644 index 00000000000..8346e24f0bc --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/query.rego @@ -0,0 +1,62 @@ +package Cx + +ensure_array(x) = x { is_array(x) } +ensure_array(x) = [x] { is_object(x) } + +# CASO 1: El bloque 'password_policy' EXISTE, pero el valor es menor a 14. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.oci_identity_authentication_policy[name] + + resource.password_policy + policies := ensure_array(resource.password_policy) + policy := policies[_] + + policy.minimum_password_length + + to_number(policy.minimum_password_length) < 14 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_authentication_policy.%s.password_policy.minimum_password_length", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'minimum_password_length' should be 14 or greater", + "keyActualValue": sprintf("'minimum_password_length' is %d", [to_number(policy.minimum_password_length)]), + } +} + +# CASO 2: El bloque 'password_policy' EXISTE, pero FALTA el atributo 'minimum_password_length'. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.oci_identity_authentication_policy[name] + + resource.password_policy + policies := ensure_array(resource.password_policy) + policy := policies[_] + + object.get(policy, "minimum_password_length", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_authentication_policy.%s.password_policy", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'minimum_password_length' should be explicitly defined (>= 14)", + "keyActualValue": "'minimum_password_length' is missing (using default)", + } +} + +# CASO 3: El bloque 'password_policy' NO EXISTE en absoluto. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.oci_identity_authentication_policy[name] + + not resource.password_policy + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_authentication_policy.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'password_policy' block should be defined with 'minimum_password_length' >= 14", + "keyActualValue": "'password_policy' block is missing", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/negative1.tf b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/negative1.tf new file mode 100644 index 00000000000..b302379143f --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/negative1.tf @@ -0,0 +1,9 @@ +resource "oci_identity_authentication_policy" "secure_policy" { + compartment_id = "ocid1.tenancy..." + + password_policy { + # CORRECTO: >= 14 + minimum_password_length = 14 + is_lowercase_characters_required = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive1.tf b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive1.tf new file mode 100644 index 00000000000..4b2edc6c686 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive1.tf @@ -0,0 +1,9 @@ +resource "oci_identity_authentication_policy" "weak_policy" { + compartment_id = "ocid1.tenancy..." + + password_policy { + # FALLO: 8 es menor que 14 + minimum_password_length = 8 + is_lowercase_characters_required = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive2.tf b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive2.tf new file mode 100644 index 00000000000..02c3737ba9b --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive2.tf @@ -0,0 +1,8 @@ +resource "oci_identity_authentication_policy" "missing_attr" { + compartment_id = "ocid1.tenancy..." + + password_policy { + # FALLO: Falta minimum_password_length + is_lowercase_characters_required = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive3.tf b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive3.tf new file mode 100644 index 00000000000..6d4ed4fa8d6 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive3.tf @@ -0,0 +1,4 @@ +resource "oci_identity_authentication_policy" "missing_block" { + compartment_id = "ocid1.tenancy..." + # FALLO: No hay bloque password_policy +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive_expected_result.json new file mode 100644 index 00000000000..7eba7d84d20 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "OCI IAM Password Minimum Length", + "severity": "MEDIUM", + "line": 6, + "fileName": "positive1.tf" + }, + { + "queryName": "OCI IAM Password Minimum Length", + "severity": "MEDIUM", + "line": 4, + "fileName": "positive2.tf" + }, + { + "queryName": "OCI IAM Password Minimum Length", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/README.md b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/README.md new file mode 100644 index 00000000000..45c14e44e54 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/README.md @@ -0,0 +1,55 @@ +# Regla KICS: OCI IAM Password Reuse Prevention (Manual) + +## Descripción General + +Esta regla informativa (INFO) audita las políticas de contraseñas en **Oracle Cloud Infrastructure (OCI)** para asegurar que se impida la reutilización de credenciales antiguas. + +El **CIS Oracle Cloud Infrastructure Benchmark** recomienda configurar el historial de contraseñas para recordar las últimas **24** contraseñas utilizadas, evitando así que los usuarios alternen entre un conjunto pequeño de contraseñas conocidas. + +La regla maneja dos escenarios distintos dependiendo de la arquitectura de identidad utilizada en OCI: + +1. **Identity Domains (Moderno):** Audita el recurso `oci_identity_domains_password_policy`. El atributo correcto para controlar el historial es `num_passwords_in_history`. +2. **IAM Clásico (Legacy):** Audita el recurso `oci_identity_authentication_policy`. Este recurso antiguo no permite configurar el historial de contraseñas a través de Terraform, por lo que requiere validación manual en la consola. + +## Lógica de la Regla + +1. **Para Identity Domains (`oci_identity_domains_password_policy`):** + * Verifica el atributo `num_passwords_in_history`. + * Si el valor es menor a 24 -> **Fallo**. + * Si el atributo no está definido -> **Fallo** (se asume configuración insegura/desconocida). + +2. **Para IAM Clásico (`oci_identity_authentication_policy`):** + * Genera siempre una alerta **Manual (INFO)**, indicando al auditor que debe verificar la consola de OCI. + +## Casos de Fallo Detectados + +### Caso 1: Historial Insuficiente (Identity Domains) +* **Descripción:** La política define `num_passwords_in_history` con un valor menor a 24 (ej. 5 o 10). +* **Ubicación de la Alerta:** Atributo `num_passwords_in_history`. + +### Caso 2: Atributo Faltante (Identity Domains) +* **Descripción:** Falta el atributo `num_passwords_in_history`. +* **Ubicación de la Alerta:** Recurso `oci_identity_domains_password_policy`. + +### Caso 3: Recurso Legacy (Manual Check) +* **Descripción:** Se utiliza `oci_identity_authentication_policy`. +* **Ubicación de la Alerta:** Recurso `oci_identity_authentication_policy`. + +## Recursos Involucrados +* `oci_identity_domains_password_policy` +* `oci_identity_authentication_policy` + +## Solución + +Para **Identity Domains**, establece el historial en 24 o más. + +```terraform +resource "oci_identity_domains_password_policy" "secure_policy" { + idcs_endpoint = var.idcs_endpoint + display_name = "SecurePasswordPolicy" + + # Historial de contraseñas (CIS recomienda >= 24) + num_passwords_in_history = 24 + + schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/metadata.json b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/metadata.json new file mode 100644 index 00000000000..9c7e71e0bdd --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "fc42ff43-3c72-41d1-b5fb-3beebd4efe15", + "queryName": "OCI IAM Password Reuse Prevention (Manual)", + "severity": "INFO", + "category": "Identity and Access Management", + "descriptionText": "CIS Benchmark recommends preventing password reuse for at least the last 24 passwords. Check 'num_passwords_in_history' in 'oci_identity_domains_password_policy'. For legacy 'oci_identity_authentication_policy', this requires manual console verification.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/identity_domains_password_policy", + "platform": "Terraform", + "descriptionID": "fc42ff43", + "cloudProvider": "oci", + "cwe": "CWE-261", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/query.rego b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/query.rego new file mode 100644 index 00000000000..2eee491d363 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/query.rego @@ -0,0 +1,47 @@ +package Cx + +# CASO 1: Identity Domains - Historial insuficiente (< 24). +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.oci_identity_domains_password_policy[name] + + policy.num_passwords_in_history < 24 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_domains_password_policy.%s.num_passwords_in_history", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'num_passwords_in_history' should be >= 24", + "keyActualValue": sprintf("Current history size is %d", [policy.num_passwords_in_history]), + } +} + +# CASO 2: Identity Domains - Atributo faltante. +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.oci_identity_domains_password_policy[name] + + object.get(policy, "num_passwords_in_history", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_domains_password_policy.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'num_passwords_in_history' should be defined (>= 24)", + "keyActualValue": "'num_passwords_in_history' is missing", + } +} + +# CASO 3: IAM Clásico (Legacy) - Manual. +CxPolicy[result] { + doc := input.document[i] + _ := doc.resource.oci_identity_authentication_policy[name] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_authentication_policy.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "Password reuse prevention should be enabled (History >= 24)", + "keyActualValue": "Legacy resource does not support password history settings in Terraform. Manual console check required.", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/negative1.tf b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/negative1.tf new file mode 100644 index 00000000000..e551ec5346e --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/negative1.tf @@ -0,0 +1,9 @@ +resource "oci_identity_domains_password_policy" "secure_policy" { + idcs_endpoint = "https://idcs-..." + name = "SecurePolicy" + + # CORRECTO: >= 24 + num_passwords_in_history = 24 + + schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive1.tf b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive1.tf new file mode 100644 index 00000000000..8087a0e07ff --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive1.tf @@ -0,0 +1,9 @@ +resource "oci_identity_domains_password_policy" "weak_history" { + idcs_endpoint = "https://idcs-..." + name = "WeakHistoryPolicy" + + # FALLO: 5 es menor que 24 + num_passwords_in_history = 5 + + schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive2.tf b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive2.tf new file mode 100644 index 00000000000..c57df4600ae --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive2.tf @@ -0,0 +1,8 @@ +resource "oci_identity_domains_password_policy" "missing_attr" { + idcs_endpoint = "https://idcs-..." + name = "MissingAttrPolicy" + + # FALLO: Falta num_passwords_in_history + password_min_length = 14 + schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive3.tf b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive3.tf new file mode 100644 index 00000000000..63251d16ce5 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive3.tf @@ -0,0 +1,8 @@ +resource "oci_identity_authentication_policy" "legacy_policy" { + compartment_id = "ocid1.tenancy..." + + # FALLO: Recurso Legacy requiere chequeo manual + password_policy { + minimum_password_length = 14 + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..0376d3837d8 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "OCI IAM Password Reuse Prevention (Manual)", + "severity": "INFO", + "line": 6, + "fileName": "positive1.tf" + }, + { + "queryName": "OCI IAM Password Reuse Prevention (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + }, + { + "queryName": "OCI IAM Password Reuse Prevention (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/README.md new file mode 100644 index 00000000000..dfd823e140c --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/README.md @@ -0,0 +1,65 @@ +# Regla KICS: Notificación para Cambios en Políticas de IAM en OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio (creación, actualización o eliminación) en las políticas de IAM de la cuenta de OCI. + +Las políticas de IAM son el mecanismo central que define "quién puede hacer qué" en OCI. Un cambio no autorizado en una política puede conceder permisos excesivos, eliminar controles de seguridad o abrir la puerta a un atacante para que tome el control de los recursos. La monitorización en tiempo real de estos cambios es, por tanto, una de las auditorías de seguridad más importantes. + +## Lógica de la Regla + +La política valida que exista una configuración activa para capturar los tres eventos críticos de políticas: +1. `com.oraclecloud.identity.createpolicy` +2. `com.oraclecloud.identity.updatepolicy` +3. `com.oraclecloud.identity.deletepolicy` + +## Casos de Fallo Detectados + +--- +### Caso 1: Regla Ausente (Missing) +* **Descripción:** No se encuentra ninguna regla de eventos que monitorice cambios en políticas de IAM en todo el proyecto. +* **Ubicación:** Bloque `provider "oci"`. + +--- +### Caso 2: Regla Incompleta (Incomplete) +* **Descripción:** Existe una regla que monitoriza algunos eventos de políticas (ej. `createpolicy`), pero omite otros críticos (ej. `deletepolicy`). +* **Ubicación:** Atributo `condition` del recurso. + +--- +### Caso 3: Regla Deshabilitada (Disabled) +* **Descripción:** Existe una regla completa con todos los eventos, pero está explícitamente deshabilitada (`is_enabled = false`). +* **Ubicación:** Atributo `is_enabled`. + +## Recurso Involucrado + +* `oci_events_rule` + +## Solución + +```terraform +resource "oci_events_rule" "iam_policy_change_rule" { + display_name = "audit-rule-for-iam-policy-changes" + description = "Alerts on any creation, update, or deletion of IAM policies" + compartment_id = var.tenancy_ocid + is_enabled = true + + condition = jsonencode({ + eventType = [ + "com.oraclecloud.identity.createpolicy", + "com.oraclecloud.identity.updatepolicy", + "com.oraclecloud.identity.deletepolicy" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = oci_ons_notification_topic.security_alerts_topic.id + } + } +} + +resource "oci_ons_notification_topic" "security_alerts_topic" { + compartment_id = var.compartment_id + name = "security-alerts-topic" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json new file mode 100644 index 00000000000..2dd9f4cfdbd --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "a151d9a0-d626-447f-beab-11d53aeb0f2b", + "queryName": "Event Rule for IAM Policy Changes is Missing", + "severity": "HIGH", + "category": "Access Control", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to IAM policies. Auditing the creation, modification, and deletion of IAM policies is a critical security measure to detect unauthorized changes to permissions within the tenancy.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "a151d9a0", + "cloudProvider": "oci", + "cwe": "CWE-778", + "riskScore": 4.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego new file mode 100644 index 00000000000..b51144a73ee --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego @@ -0,0 +1,76 @@ +package Cx + +expected_event_types := [ + "com.oraclecloud.identity.createpolicy", + "com.oraclecloud.identity.updatepolicy", + "com.oraclecloud.identity.deletepolicy" +] + +# REGLA 1: Missing (Global) +# No existe NINGUNA regla en el proyecto que monitoree eventos de Políticas IAM. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_policy_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_policy_rule) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for IAM Policy changes should exist", + "keyActualValue": "No 'oci_events_rule' found for IAM Policy changes", + } +} + +# REGLA 2: Incomplete (Local) +# La regla existe y mira eventos de Políticas, pero le falta alguno de los 3 requeridos. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 3 IAM Policy events (create, update, delete)", + "keyActualValue": sprintf("The rule is missing %d IAM Policy event(s)", [missing_count]), + } +} + +# REGLA 3: Disabled (Local) +# La regla tiene todos los eventos correctos, pero está deshabilitada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) == count(expected_event_types) + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/negative1.tf b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/negative1.tf new file mode 100644 index 00000000000..9ffa462982d --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/negative1.tf @@ -0,0 +1,25 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "correct_rule" { + display_name = "CorrectPolicyRule" + compartment_id = "ocid1.tenancy.oc1.." + is_enabled = true + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identity.createpolicy", + "com.oraclecloud.identity.updatepolicy", + "com.oraclecloud.identity.deletepolicy" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic.oc1.." + is_enabled = true + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive1.tf b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive1.tf new file mode 100644 index 00000000000..b72e7fdfbf1 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive1.tf @@ -0,0 +1,10 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_policy" "test_policy" { + name = "test-policy" + description = "Policy for testing" + compartment_id = "ocid1.tenancy.oc1.." + statements = ["Allow group Administrators to manage all-resources in tenancy"] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive2.tf new file mode 100644 index 00000000000..48dcc79c9b4 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive2.tf @@ -0,0 +1,25 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "incomplete_rule" { + display_name = "IncompletePolicyRule" + compartment_id = "ocid1.tenancy.oc1.." + is_enabled = true + + # FALLO: Falta "deletepolicy" + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identity.createpolicy", + "com.oraclecloud.identity.updatepolicy" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic.oc1.." + is_enabled = true + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive3.tf b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive3.tf new file mode 100644 index 00000000000..6b515b92330 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive3.tf @@ -0,0 +1,26 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "disabled_rule" { + display_name = "DisabledPolicyRule" + compartment_id = "ocid1.tenancy.oc1.." + description = "Rule with all events but disabled" + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identity.createpolicy", + "com.oraclecloud.identity.updatepolicy", + "com.oraclecloud.identity.deletepolicy" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic.oc1.." + } + } + + is_enabled = false +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..3653af125a1 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Event Rule for IAM Policy Changes is Missing", + "severity": "HIGH", + "line": 2, + "fileName": "positive1.tf" + }, + { + "queryName": "Event Rule for IAM Policy Changes is Missing", + "severity": "HIGH", + "line": 11, + "fileName": "positive2.tf" + }, + { + "queryName": "Event Rule for IAM Policy Changes is Missing", + "severity": "HIGH", + "line": 25, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_service_admins_manual/README.md b/assets/queries/terraform/oci/oci_iam_service_admins_manual/README.md new file mode 100644 index 00000000000..3fedb6262a9 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_service_admins_manual/README.md @@ -0,0 +1,46 @@ +# Regla KICS: OCI Service Level Admins (Manual) + +## Descripción General + +Esta regla informativa (INFO) audita las políticas de **OCI IAM** (`oci_identity_policy`). + +Según el Benchmark CIS para Oracle Cloud, se debe evitar el uso excesivo del grupo de administradores predeterminado (que tiene acceso total a la tenencia). En su lugar, se deben crear **Administradores de Nivel de Servicio** (Service Level Admins). Esto implica crear grupos y políticas específicas para gestionar verticales tecnológicas, por ejemplo: +* `NetworkAdmins`: `manage virtual-network-family` +* `ComputeAdmins`: `manage instance-family` +* `StorageAdmins`: `manage object-family` + +Esta regla detecta cualquier política que otorgue el verbo `manage` para que un auditor verifique que está correctamente acotada (es decir, que no sea `manage all-resources` a menos que sea estrictamente necesario). + +## Lógica de la Regla + +1. Identifica recursos `oci_identity_policy`. +2. Analiza el array `statements`. +3. Si una sentencia contiene la palabra exacta `manage` (usando detección de límite de palabra y sin distinguir mayúsculas/minúsculas), genera una alerta para su revisión manual. + +## Casos de Fallo Detectados + +### Caso 1: Privilegios de Gestión (Manage) + +* **Descripción:** Se detectó una política que otorga control total (`manage`) sobre algún recurso o familia de recursos. +* **Acción:** Verificar que el grupo asignado y el recurso gestionado ("family") corresponden a una segregación de funciones adecuada. +* **Ubicación de la Alerta:** Atributo `statements` en `oci_identity_policy`. + +## Recurso Involucrado + +* `oci_identity_policy` + +## Solución + +Define políticas granulares por familia de servicios. + +```terraform +resource "oci_identity_policy" "network_admin_policy" { + name = "NetworkAdminPolicy" + description = "Policy for Network Admins" + compartment_id = var.tenancy_ocid + + statements = [ + "Allow group NetworkAdmins to manage virtual-network-family in tenancy", + "Allow group NetworkAdmins to read all-resources in tenancy" + ] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_service_admins_manual/metadata.json b/assets/queries/terraform/oci/oci_iam_service_admins_manual/metadata.json new file mode 100644 index 00000000000..ecb116d27ae --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_service_admins_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "0401f017-91ee-4019-842a-f940d08b22aa", + "queryName": "OCI Service Level Admins (Manual)", + "severity": "INFO", + "category": "Identity and Access Management", + "descriptionText": "CIS controls recommend creating specific Service Level Administrators (e.g., Network Admin, Storage Admin) rather than relying solely on the default Tenancy Administrator. Review this policy to ensure it delegates 'manage' permissions for specific resource families to appropriate groups, implementing Least Privilege.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/identity_policy", + "platform": "Terraform", + "cloudProvider": "oci", + "cwe": "CWE-276", + "descriptionID": "0401f017", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_service_admins_manual/query.rego b/assets/queries/terraform/oci/oci_iam_service_admins_manual/query.rego new file mode 100644 index 00000000000..5e2ce35faa0 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_service_admins_manual/query.rego @@ -0,0 +1,19 @@ +package Cx + +# REGLA: Auditoría Manual de Políticas de Gestión (Service Admins). +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.oci_identity_policy[name] + + statement := policy.statements[_] + + regex.match("(?i)\\bmanage\\b", statement) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_policy.%s.statements", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Policy should grant 'manage' on specific families to specific groups (Manual Review)", + "keyActualValue": sprintf("Policy statement grants management privileges: '%s'. Manual review required.", [statement]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/negative1.tf b/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/negative1.tf new file mode 100644 index 00000000000..0f5443c23d9 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/negative1.tf @@ -0,0 +1,14 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_policy" "auditors" { + name = "AuditPolicy" + description = "Read only access" + compartment_id = "ocid1.tenancy..." + + statements = [ + "Allow group Auditors to read all-resources in tenancy", + "Allow group Auditors to inspect users in tenancy" + ] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/negative2.tf b/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/negative2.tf new file mode 100644 index 00000000000..bd5c0be5230 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/negative2.tf @@ -0,0 +1,13 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_policy" "project_managers" { + name = "ProjectManagersPolicy" + compartment_id = "ocid1.tenancy..." + + statements = [ + "Allow group ProjectManagers to read instance-family in compartment ProjectA", + "Allow group KeyManagementUsers to use keys in tenancy" + ] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/positive1.tf b/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/positive1.tf new file mode 100644 index 00000000000..3d98f40f89f --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/positive1.tf @@ -0,0 +1,23 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_policy" "network_admins" { + name = "NetworkAdmins" + description = "Admins for VCN" + compartment_id = "ocid1.tenancy..." + + statements = [ + "Allow group NetworkAdmins to manage virtual-network-family in tenancy" + ] +} + +resource "oci_identity_policy" "super_admin" { + name = "SuperAdmins" + description = "God mode" + compartment_id = "ocid1.tenancy..." + + statements = [ + "Allow group SuperUsers to MANAGE all-resources in tenancy" + ] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..c85bd5b053a --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "OCI Service Level Admins (Manual)", + "severity": "INFO", + "line": 10, + "fileName": "positive1.tf" + }, + { + "queryName": "OCI Service Level Admins (Manual)", + "severity": "INFO", + "line": 20, + "fileName": "positive1.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/README.md new file mode 100644 index 00000000000..641c35d5c0a --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/README.md @@ -0,0 +1,57 @@ +# Regla KICS: Notificación para Cambios en Usuarios de IAM en OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio en el ciclo de vida de los usuarios de IAM en la cuenta de OCI. + +La gestión de identidades de usuario es una superficie de ataque principal. Un atacante podría crear un usuario nuevo y oculto, modificar un usuario existente para escalar privilegios, o deshabilitar cuentas legítimas para causar una denegación de servicio. + +## Lógica de la Regla + +La política verifica que exista configuración activa para capturar los cinco tipos de eventos que constituyen el ciclo de vida de un usuario de IAM: +1. `com.oraclecloud.identity.createuser` +2. `com.oraclecloud.identity.updateuser` +3. `com.oraclecloud.identity.deleteuser` +4. `com.oraclecloud.identity.enableuser` +5. `com.oraclecloud.identity.disableuser` + +## Casos de Fallo Detectados + +### Caso 1: Regla Ausente (Missing) +* **Descripción:** No existe ninguna regla configurada para usuarios en el proyecto. +* **Ubicación:** Bloque `provider "oci"`. + +### Caso 2: Regla Incompleta (Incomplete) +* **Descripción:** Existe una regla para usuarios, pero le faltan eventos (ej. monitorea `create` pero olvida `disable`). +* **Ubicación:** Atributo `condition`. + +### Caso 3: Regla Deshabilitada (Disabled) +* **Descripción:** Existe una regla relevante pero está explícitamente deshabilitada (`is_enabled = false`). +* **Ubicación:** Atributo `is_enabled` dentro del recurso `oci_events_rule`. + +## Solución + +```terraform +resource "oci_events_rule" "iam_user_change_rule" { + display_name = "audit-rule-for-iam-user-changes" + description = "Alerts on any lifecycle change of IAM users" + compartment_id = var.tenancy_ocid + is_enabled = true + + condition = jsonencode({ + eventType = [ + "com.oraclecloud.identity.createuser", + "com.oraclecloud.identity.updateuser", + "com.oraclecloud.identity.deleteuser", + "com.oraclecloud.identity.enableuser", + "com.oraclecloud.identity.disableuser" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = oci_ons_notification_topic.security_alerts_topic.id + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json new file mode 100644 index 00000000000..abb44be36ee --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "b1405757-feb9-4218-b685-ff53775ddf48", + "queryName": "Event Rule for IAM User Changes is Missing", + "severity": "HIGH", + "category": "Access Control", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to IAM users. Auditing the full lifecycle of user accounts (creation, modification, deletion, enable/disable) is a critical security measure to detect unauthorized account creation or privilege changes.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "b1405757", + "cloudProvider": "oci", + "cwe": "CWE-778", + "riskScore": 6.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego new file mode 100644 index 00000000000..af9fd41e8e7 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego @@ -0,0 +1,78 @@ +package Cx + +expected_event_types := [ + "com.oraclecloud.identity.createuser", + "com.oraclecloud.identity.updateuser", + "com.oraclecloud.identity.deleteuser", + "com.oraclecloud.identity.enableuser", + "com.oraclecloud.identity.disableuser" +] + +# REGLA 1: Missing (Global) +# No existe NINGUNA regla en el proyecto que monitoree eventos de usuarios. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_user_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_user_rule) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for IAM User changes (create, update, delete, enable, disable) should exist", + "keyActualValue": "No 'oci_events_rule' found for IAM User changes", + } +} + +# REGLA 2: Incomplete (Local) +# La regla existe y es relevante, pero le falta alguno de los 5 eventos. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 5 IAM User events", + "keyActualValue": sprintf("The rule is missing %d IAM User event(s)", [missing_count]), + } +} + +# REGLA 3: Disabled (Local) +# Si es una regla de Usuarios (relevante) y está apagada -> FALLO CRÍTICO. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) > 0 + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/negative1.tf b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/negative1.tf new file mode 100644 index 00000000000..db6c7e4a0c3 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/negative1.tf @@ -0,0 +1,27 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "correct_user_rule" { + display_name = "CorrectUserRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identity.createuser", + "com.oraclecloud.identity.updateuser", + "com.oraclecloud.identity.deleteuser", + "com.oraclecloud.identity.enableuser", + "com.oraclecloud.identity.disableuser" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + is_enabled = true + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive1.tf b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive1.tf new file mode 100644 index 00000000000..df3bc9c3799 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive1.tf @@ -0,0 +1,8 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_user" "test_user" { + name = "test-user" + description = "Test user" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive2.tf new file mode 100644 index 00000000000..41ad4ef1343 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive2.tf @@ -0,0 +1,25 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "incomplete_user_rule" { + display_name = "IncompleteUserRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + # FALLO: Faltan enableuser y disableuser + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identity.createuser", + "com.oraclecloud.identity.updateuser", + "com.oraclecloud.identity.deleteuser" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive3.tf b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive3.tf new file mode 100644 index 00000000000..395f73b60a9 --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive3.tf @@ -0,0 +1,28 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "disabled_user_rule" { + display_name = "DisabledUserRule" + compartment_id = "ocid1.tenancy..." + description = "Has all events but is disabled" + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identity.createuser", + "com.oraclecloud.identity.updateuser", + "com.oraclecloud.identity.deleteuser", + "com.oraclecloud.identity.enableuser", + "com.oraclecloud.identity.disableuser" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } + + is_enabled = false +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..2c81ca8e5ee --- /dev/null +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Event Rule for IAM User Changes is Missing", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Event Rule for IAM User Changes is Missing", + "severity": "HIGH", + "line": 11, + "fileName": "positive2.tf" + }, + { + "queryName": "Event Rule for IAM User Changes is Missing", + "severity": "HIGH", + "line": 27, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/README.md new file mode 100644 index 00000000000..aee2de0105c --- /dev/null +++ b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/README.md @@ -0,0 +1,47 @@ +# Regla KICS: Notificación para Cambios en el Proveedor de Identidad de OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cambios en los proveedores de identidad (Identity Providers) de la cuenta de OCI. + +Los proveedores de identidad son un componente crítico de la seguridad, ya que controlan la federación de usuarios. Un atacante que consiga modificar o añadir un proveedor de identidad podría redirigir los inicios de sesión o federar un dominio malicioso para obtener acceso a la cuenta. Por lo tanto, cualquier cambio en esta configuración debe ser notificado y auditado inmediatamente. + +## Lógica de la Regla + +La política verifica que exista configuración activa para capturar el siguiente evento crítico: +* `com.oraclecloud.identitycontrolplane.updateidentityprovider` + +## Casos de Fallo Detectados + +### Caso 1: Regla Ausente (Missing) +* **Descripción:** No existe ninguna regla configurada para monitorear Identity Providers en el proyecto. +* **Ubicación de la Alerta:** Bloque `provider "oci"`. + +### Caso 2: Regla Deshabilitada (Disabled) +* **Descripción:** Existe una regla que monitorea el evento correcto, pero está explícitamente deshabilitada (`is_enabled = false`). +* **Ubicación de la Alerta:** Atributo `is_enabled` dentro del recurso `oci_events_rule`. + +## Solución + +Para solucionar el problema, asegúrate de tener una regla habilitada con el evento correcto: + +```terraform +resource "oci_events_rule" "iam_idp_change_rule" { + display_name = "audit-rule-for-identity-provider-changes" + description = "Alerts on any modification to Identity Providers" + compartment_id = var.tenancy_ocid + is_enabled = true + + condition = jsonencode({ + eventType = [ + "com.oraclecloud.identitycontrolplane.updateidentityprovider" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = oci_ons_notification_topic.security_alerts_topic.id + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json new file mode 100644 index 00000000000..12d91b5fcb1 --- /dev/null +++ b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "0a077b15-dc77-4490-810b-4e34f1b55500", + "queryName": "Event Rule for Identity Provider Changes is Missing", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Identity Providers. Monitoring these changes is critical for detecting potentially malicious activity, such as the addition of an unauthorized external identity provider.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "0a077b15", + "cloudProvider": "oci", + "cwe": "CWE-778", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego new file mode 100644 index 00000000000..5b650d7bc6a --- /dev/null +++ b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego @@ -0,0 +1,43 @@ +package Cx + +expected_event := "com.oraclecloud.identitycontrolplane.updateidentityprovider" + +# REGLA 1: Missing (Global) +# No existe NINGUNA regla en el proyecto que monitoree el evento de Identity Provider. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_idp_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + contains(rule.condition, expected_event) + ] + + count(any_idp_rule) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for Identity Provider changes should exist", + "keyActualValue": "No 'oci_events_rule' found for Identity Provider changes", + } +} + +# REGLA 2: Disabled (Local) +# La regla existe y monitorea IdP, pero está deshabilitada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + contains(rule.condition, expected_event) + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/negative1.tf b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/negative1.tf new file mode 100644 index 00000000000..93206fbcabf --- /dev/null +++ b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/negative1.tf @@ -0,0 +1,23 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "correct_idp_rule" { + display_name = "CorrectIdPRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identitycontrolplane.updateidentityprovider" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + is_enabled = true + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive1.tf b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive1.tf new file mode 100644 index 00000000000..3ae5013b74c --- /dev/null +++ b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive1.tf @@ -0,0 +1,20 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "other_rule" { + display_name = "InstanceRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + condition = jsonencode({ + "eventType": ["com.oraclecloud.compute.instance.launch.end"] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive2.tf new file mode 100644 index 00000000000..d17dc30b7d6 --- /dev/null +++ b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive2.tf @@ -0,0 +1,24 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "disabled_idp_rule" { + display_name = "DisabledIdPRule" + compartment_id = "ocid1.tenancy..." + description = "Monitors IdP but is disabled" + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identitycontrolplane.updateidentityprovider" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } + + is_enabled = false +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..5159aacc2cc --- /dev/null +++ b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Event Rule for Identity Provider Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Event Rule for Identity Provider Changes is Missing", + "severity": "MEDIUM", + "line": 23, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/README.md new file mode 100644 index 00000000000..79e56c40b98 --- /dev/null +++ b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/README.md @@ -0,0 +1,45 @@ +# Regla KICS: Notificación para Cambios de Mapeo de Grupos de IdP en OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cambios en los mapeos de grupos de los proveedores de identidad (IdP) de la cuenta de OCI. + +El mapeo de grupos de un IdP es lo que traduce la pertenencia a un grupo en un proveedor de identidad externo (como Azure AD, Okta, etc.) a la pertenencia a un grupo de IAM en OCI. Un cambio no autorizado en estos mapeos podría escalar privilegios de forma masiva y silenciosa. + +## Lógica de la Regla + +La política verifica que exista configuración activa para capturar el siguiente evento crítico: +* `com.oraclecloud.identitycontrolplane.updateidpgroupmapping` + +## Casos de Fallo Detectados + +### Caso 1: Regla Ausente (Missing) +* **Descripción:** No existe ninguna regla configurada para monitorear cambios en mapeos de grupos de IdP. +* **Ubicación de la Alerta:** Bloque `provider "oci"`. + +### Caso 2: Regla Deshabilitada (Disabled) +* **Descripción:** Existe una regla que monitorea el evento correcto, pero está explícitamente deshabilitada (`is_enabled = false`). +* **Ubicación de la Alerta:** Atributo `is_enabled` dentro del recurso `oci_events_rule`. + +## Solución + +```terraform +resource "oci_events_rule" "iam_idp_group_mapping_change_rule" { + display_name = "audit-rule-for-idp-group-mapping-changes" + description = "Alerts on any modification to IdP group mappings" + compartment_id = var.tenancy_ocid + is_enabled = true + + condition = jsonencode({ + eventType = [ + "com.oraclecloud.identitycontrolplane.updateidpgroupmapping" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = oci_ons_notification_topic.security_alerts_topic.id + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json new file mode 100644 index 00000000000..cbd08451173 --- /dev/null +++ b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "1f106aa1-a994-4a11-afbc-109f31947d6a", + "queryName": "Event Rule for IdP Group Mapping Changes is Missing", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Identity Provider (IdP) group mappings. Auditing these changes is vital for detecting unauthorized modifications to user group permissions.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "1f106aa1", + "cloudProvider": "oci", + "cwe": "CWE-778", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego new file mode 100644 index 00000000000..18e7c22d871 --- /dev/null +++ b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego @@ -0,0 +1,43 @@ +package Cx + +expected_event := "com.oraclecloud.identitycontrolplane.updateidpgroupmapping" + +# REGLA 1: Missing (Global) +# No existe NINGUNA regla en el proyecto que monitoree el evento de IdP Group Mapping. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_mapping_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + contains(rule.condition, expected_event) + ] + + count(any_mapping_rule) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for IdP group mapping changes should exist", + "keyActualValue": "No 'oci_events_rule' found for IdP group mapping changes", + } +} + +# REGLA 2: Disabled (Local) +# La regla existe y monitorea el mapeo, pero está deshabilitada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + contains(rule.condition, expected_event) + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/negative1.tf b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/negative1.tf new file mode 100644 index 00000000000..9c48a70b701 --- /dev/null +++ b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/negative1.tf @@ -0,0 +1,23 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "correct_mapping_rule" { + display_name = "CorrectMappingRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identitycontrolplane.updateidpgroupmapping" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + is_enabled = true + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive1.tf b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive1.tf new file mode 100644 index 00000000000..765a4165e1b --- /dev/null +++ b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive1.tf @@ -0,0 +1,20 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "other_rule" { + display_name = "NetworkRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + condition = jsonencode({ + "eventType": ["com.oraclecloud.virtualnetwork.createvcn"] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive2.tf new file mode 100644 index 00000000000..c4cfa1d649a --- /dev/null +++ b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive2.tf @@ -0,0 +1,24 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "disabled_mapping_rule" { + display_name = "DisabledMappingRule" + compartment_id = "ocid1.tenancy..." + description = "Monitors IdP Mapping but is disabled" + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identitycontrolplane.updateidpgroupmapping" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } + + is_enabled = false +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..fc56ddcb96d --- /dev/null +++ b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Event Rule for IdP Group Mapping Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Event Rule for IdP Group Mapping Changes is Missing", + "severity": "MEDIUM", + "line": 23, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/README.md b/assets/queries/terraform/oci/oci_instance_transit_encryption/README.md new file mode 100644 index 00000000000..3d6ee853be2 --- /dev/null +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/README.md @@ -0,0 +1,54 @@ +# Regla KICS: OCI Instance In-Transit Encryption Disabled + +## Descripción General + +Esta regla de severidad **MEDIA** audita el recurso `oci_core_instance` para verificar que el cifrado en tránsito esté habilitado. + +En OCI, la opción `is_pv_encryption_in_transit_enabled` dentro de `launch_options` habilita el cifrado de los datos transferidos entre la instancia de computación y los volúmenes de arranque o de bloques paravirtualizados. Esto asegura la confidencialidad de los datos mientras viajan por la red interna del centro de datos. + +## Lógica de la Regla + +La regla verifica tres escenarios distintos: + +1. **Valor Incorrecto:** El bloque `launch_options` existe y el atributo `is_pv_encryption_in_transit_enabled` está explícitamente en `false`. +2. **Atributo Faltante:** El bloque `launch_options` existe, pero falta el atributo `is_pv_encryption_in_transit_enabled` (lo que puede aplicar un valor por defecto inseguro). +3. **Bloque Faltante:** No existe el bloque `launch_options` en la definición del recurso. + +## Casos de Fallo Detectados + +### Caso 1: Cifrado Deshabilitado Explícitamente +* **Descripción:** Se ha configurado `is_pv_encryption_in_transit_enabled = false`. +* **Ubicación de la Alerta:** Atributo `is_pv_encryption_in_transit_enabled`. + +### Caso 2: Atributo Faltante en Opciones +* **Descripción:** El bloque `launch_options` está definido, pero no se especifica el cifrado, confiando en el valor predeterminado del proveedor. +* **Ubicación de la Alerta:** Bloque `launch_options`. + +### Caso 3: Bloque de Opciones Ausente +* **Descripción:** La instancia no define `launch_options`, por lo que no se está forzando el cifrado en tránsito. +* **Ubicación de la Alerta:** Recurso `oci_core_instance`. + +## Recurso Involucrado +* `oci_core_instance` + +## Solución + +Habilita explícitamente el cifrado en tránsito dentro de las opciones de lanzamiento. + +```terraform +resource "oci_core_instance" "secure_instance" { + availability_domain = var.availability_domain + compartment_id = var.compartment_id + shape = "VM.Standard.E4.Flex" + + # Bloque requerido para la seguridad en tránsito + launch_options { + boot_volume_type = "PARAVIRTUALIZED" + is_pv_encryption_in_transit_enabled = true + } + + source_details { + source_type = "image" + source_id = var.image_id + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json b/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json new file mode 100644 index 00000000000..e5173108120 --- /dev/null +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "c29ef8f7-33bc-4788-9085-3a561c91f7d1", + "queryName": "OCI Instance In-Transit Encryption Disabled", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Compute instances should have in-transit encryption enabled for data moving between the instance and block storage. This is configured via 'is_pv_encryption_in_transit_enabled' in the 'launch_options' block.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_instance#is_pv_encryption_in_transit_enabled", + "platform": "Terraform", + "descriptionID": "c29ef8f7", + "cloudProvider": "oci", + "cwe": "CWE-311", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/query.rego b/assets/queries/terraform/oci/oci_instance_transit_encryption/query.rego new file mode 100644 index 00000000000..2dac4c0608d --- /dev/null +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/query.rego @@ -0,0 +1,58 @@ +package Cx + +ensure_array(x) = x { is_array(x) } +ensure_array(x) = [x] { is_object(x) } + +# CASO 1: El bloque launch_options existe, pero la opción está explícitamente en FALSE. +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.oci_core_instance[name] + + options := ensure_array(instance.launch_options) + opt := options[_] + + opt.is_pv_encryption_in_transit_enabled == false + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_core_instance.%s.launch_options.is_pv_encryption_in_transit_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_pv_encryption_in_transit_enabled' should be set to true", + "keyActualValue": "'is_pv_encryption_in_transit_enabled' is set to false", + } +} + +# CASO 2: El bloque launch_options existe, pero FALTA el atributo (default es false/inseguro). +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.oci_core_instance[name] + + options := ensure_array(instance.launch_options) + opt := options[_] + + object.get(opt, "is_pv_encryption_in_transit_enabled", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_core_instance.%s.launch_options", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'is_pv_encryption_in_transit_enabled' should be defined and set to true", + "keyActualValue": "'is_pv_encryption_in_transit_enabled' is missing", + } +} + +# CASO 3: FALTA el bloque launch_options completo. +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.oci_core_instance[name] + + not instance.launch_options + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_core_instance.%s", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'launch_options' block with 'is_pv_encryption_in_transit_enabled = true' should be defined", + "keyActualValue": "'launch_options' block is missing", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/test/negative1.tf b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/negative1.tf new file mode 100644 index 00000000000..59c69e1a07d --- /dev/null +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/negative1.tf @@ -0,0 +1,14 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_instance" "instance_compliant" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard.E4.Flex" + + launch_options { + boot_volume_type = "PARAVIRTUALIZED" + is_pv_encryption_in_transit_enabled = true + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive1.tf b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive1.tf new file mode 100644 index 00000000000..a0fc32fdc32 --- /dev/null +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive1.tf @@ -0,0 +1,20 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_instance" "instance_explicit_false" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard.E4.Flex" + + launch_options { + boot_volume_type = "PARAVIRTUALIZED" + # FALLO: Explícitamente false (sin comentario pegado encima) + is_pv_encryption_in_transit_enabled = false + } + + source_details { + source_id = "ocid1.image..." + source_type = "image" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive2.tf b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive2.tf new file mode 100644 index 00000000000..3a1ca5f3519 --- /dev/null +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive2.tf @@ -0,0 +1,15 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_instance" "instance_missing_attribute" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard.E4.Flex" + + # El bloque existe, pero falta el atributo de encriptación + launch_options { + boot_volume_type = "PARAVIRTUALIZED" + network_type = "PARAVIRTUALIZED" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive3.tf b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive3.tf new file mode 100644 index 00000000000..a6da327c592 --- /dev/null +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive3.tf @@ -0,0 +1,15 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_instance" "instance_missing_block" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard.E4.Flex" + + # No existe el bloque launch_options + source_details { + source_id = "ocid1.image..." + source_type = "image" + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive_expected_result.json new file mode 100644 index 00000000000..2099845fc82 --- /dev/null +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "OCI Instance In-Transit Encryption Disabled", + "severity": "MEDIUM", + "line": 13, + "fileName": "positive1.tf" + }, + { + "queryName": "OCI Instance In-Transit Encryption Disabled", + "severity": "MEDIUM", + "line": 11, + "fileName": "positive2.tf" + }, + { + "queryName": "OCI Instance In-Transit Encryption Disabled", + "severity": "MEDIUM", + "line": 5, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/README.md new file mode 100644 index 00000000000..dc40f8f9440 --- /dev/null +++ b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/README.md @@ -0,0 +1,45 @@ +# Regla KICS: Notificación para Autenticación de Usuarios Locales en OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para generar notificaciones cada vez que un usuario local de IAM (no federado) se autentica en la cuenta de OCI. + +Los usuarios locales de IAM son aquellos definidos directamente en OCI. Monitorizar sus inicios de sesión es una medida de seguridad fundamental para detectar actividad sospechosa, como inicios de sesión desde ubicaciones inusuales o intentos de fuerza bruta. + +## Lógica de la Regla + +La política verifica que exista configuración activa para capturar el siguiente evento crítico: +* `com.oraclecloud.identity.localuser.authenticate` + +## Casos de Fallo Detectados + +### Caso 1: Regla Ausente (Missing) +* **Descripción:** No existe ninguna regla configurada para monitorear la autenticación de usuarios locales. +* **Ubicación de la Alerta:** Bloque `provider "oci"`. + +### Caso 2: Regla Deshabilitada (Disabled) +* **Descripción:** Existe una regla que monitorea el evento correcto, pero está explícitamente deshabilitada (`is_enabled = false`). +* **Ubicación de la Alerta:** Atributo `is_enabled` dentro del recurso `oci_events_rule`. + +## Solución + +```terraform +resource "oci_events_rule" "local_user_auth_rule" { + display_name = "audit-rule-for-local-user-authentication" + description = "Alerts on any local IAM user authentication event" + compartment_id = var.tenancy_ocid + is_enabled = true + + condition = jsonencode({ + eventType = [ + "com.oraclecloud.identity.localuser.authenticate" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = oci_ons_notification_topic.security_alerts_topic.id + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json new file mode 100644 index 00000000000..94d694b39b7 --- /dev/null +++ b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "e0c61731-a692-44d8-bbf2-8279985a4e41", + "queryName": "Event Rule for Local User Authentication is Missing", + "severity": "HIGH", + "category": "Access Control", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on authentication events from local IAM users. Auditing local user logins is a critical security measure to detect unauthorized access attempts and compromised credentials.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "e0c61731", + "cloudProvider": "oci", + "cwe": "CWE-778", + "riskScore": 6.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego new file mode 100644 index 00000000000..7bb5a1ce53d --- /dev/null +++ b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego @@ -0,0 +1,43 @@ +package Cx + +expected_event := "com.oraclecloud.identity.localuser.authenticate" + +# REGLA 1: Missing (Global) +# No existe NINGUNA regla en el proyecto que monitoree el evento de autenticación local. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_auth_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + contains(rule.condition, expected_event) + ] + + count(any_auth_rule) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for local user authentication events should exist", + "keyActualValue": "No 'oci_events_rule' found for local user authentication", + } +} + +# REGLA 2: Disabled (Local) +# La regla existe y monitorea autenticación, pero está deshabilitada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + contains(rule.condition, expected_event) + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/negative1.tf b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/negative1.tf new file mode 100644 index 00000000000..1f866cc41e8 --- /dev/null +++ b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/negative1.tf @@ -0,0 +1,23 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "correct_auth_rule" { + display_name = "CorrectAuthRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identity.localuser.authenticate" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + is_enabled = true + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive1.tf b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive1.tf new file mode 100644 index 00000000000..6b07c9992ba --- /dev/null +++ b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive1.tf @@ -0,0 +1,20 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "other_rule" { + display_name = "StorageRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + condition = jsonencode({ + "eventType": ["com.oraclecloud.objectstorage.createbucket"] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive2.tf new file mode 100644 index 00000000000..b34fdad393b --- /dev/null +++ b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive2.tf @@ -0,0 +1,24 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "disabled_auth_rule" { + display_name = "DisabledAuthRule" + compartment_id = "ocid1.tenancy..." + description = "Monitors Auth but is disabled" + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identity.localuser.authenticate" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } + + is_enabled = false +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..3f13367b2a8 --- /dev/null +++ b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Event Rule for Local User Authentication is Missing", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Event Rule for Local User Authentication is Missing", + "severity": "HIGH", + "line": 23, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/README.md new file mode 100644 index 00000000000..6c44e75e559 --- /dev/null +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/README.md @@ -0,0 +1,67 @@ +# Regla KICS: Notificación para Cambios en Gateways de Red en OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio (creación, actualización o eliminación) en los gateways de red de la cuenta de OCI. + +Los gateways de red (Internet Gateway, NAT Gateway, Service Gateway, DRG, LPG) son los puntos de entrada y salida del tráfico de una VCN. + +## Lógica de la Regla + +La política verifica que exista configuración activa para capturar los 15 eventos relacionados con el ciclo de vida de: +* Internet Gateway +* NAT Gateway +* Service Gateway +* Dynamic Routing Gateway (DRG) +* Local Peering Gateway (LPG) + +## Casos de Fallo Detectados + +### Caso 1: Regla Ausente (Missing) +* **Descripción:** No existe ninguna regla configurada para gateways en el proyecto. +* **Ubicación:** Bloque `provider "oci"`. + +### Caso 2: Regla Incompleta (Incomplete) +* **Descripción:** Existe una regla para gateways, pero le faltan tipos de eventos (ej. monitoriza Internet Gateway pero olvida DRG). +* **Ubicación:** Atributo `condition`. + +### Caso 3: Regla Deshabilitada (Disabled) +* **Descripción:** Existe una regla relevante pero está explícitamente deshabilitada (`is_enabled = false`). +* **Ubicación:** Atributo `is_enabled`. + +## Solución + +```terraform +resource "oci_events_rule" "network_gateway_change_rule" { + display_name = "audit-rule-for-network-gateway-changes" + description = "Alerts on any creation, update, or deletion of Network Gateways" + compartment_id = var.tenancy_ocid + is_enabled = true + + condition = jsonencode({ + eventType = [ + "com.oraclecloud.virtualnetwork.createinternetgateway", + "com.oraclecloud.virtualnetwork.updateinternetgateway", + "com.oraclecloud.virtualnetwork.deleteinternetgateway", + "com.oraclecloud.virtualnetwork.createnatgateway", + "com.oraclecloud.virtualnetwork.updatenatgateway", + "com.oraclecloud.virtualnetwork.deletenatgateway", + "com.oraclecloud.virtualnetwork.createservicegateway", + "com.oraclecloud.virtualnetwork.updateservicegateway", + "com.oraclecloud.virtualnetwork.deleteservicegateway", + "com.oraclecloud.virtualnetwork.createdrg", + "com.oraclecloud.virtualnetwork.updatedrg", + "com.oraclecloud.virtualnetwork.deletedrg", + "com.oraclecloud.virtualnetwork.createlocalpeeringgateway", + "com.oraclecloud.virtualnetwork.updatelocalpeeringgateway", + "com.oraclecloud.virtualnetwork.deletelocalpeeringgateway" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = oci_ons_notification_topic.security_alerts_topic.id + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json new file mode 100644 index 00000000000..b289b68450e --- /dev/null +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "e3ade454-28a1-4a0c-9905-b73e82a648c0", + "queryName": "Event Rule for Network Gateway Changes is Missing", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to all types of Network Gateways (Internet, NAT, Service, DRG, etc.). Auditing gateway changes is crucial for detecting unauthorized modifications to network ingress/egress points.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "e3ade454", + "cloudProvider": "oci", + "cwe": "CWE-778", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego new file mode 100644 index 00000000000..d2e8bf40def --- /dev/null +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego @@ -0,0 +1,88 @@ +package Cx + +expected_event_types := [ + "com.oraclecloud.virtualnetwork.createinternetgateway", + "com.oraclecloud.virtualnetwork.updateinternetgateway", + "com.oraclecloud.virtualnetwork.deleteinternetgateway", + "com.oraclecloud.virtualnetwork.createnatgateway", + "com.oraclecloud.virtualnetwork.updatenatgateway", + "com.oraclecloud.virtualnetwork.deletenatgateway", + "com.oraclecloud.virtualnetwork.createservicegateway", + "com.oraclecloud.virtualnetwork.updateservicegateway", + "com.oraclecloud.virtualnetwork.deleteservicegateway", + "com.oraclecloud.virtualnetwork.createdrg", + "com.oraclecloud.virtualnetwork.updatedrg", + "com.oraclecloud.virtualnetwork.deletedrg", + "com.oraclecloud.virtualnetwork.createlocalpeeringgateway", + "com.oraclecloud.virtualnetwork.updatelocalpeeringgateway", + "com.oraclecloud.virtualnetwork.deletelocalpeeringgateway" +] + +# REGLA 1: Missing (Global) +# No existe NINGUNA regla en el proyecto que monitoree Gateways. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_gateway_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_gateway_rule) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for Network Gateway changes should exist", + "keyActualValue": "No 'oci_events_rule' found for Network Gateway changes", + } +} + +# REGLA 2: Incomplete (Local) +# La regla existe, pero le faltan eventos (ej. tiene IGW pero falta NAT). +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 15 Network Gateway events", + "keyActualValue": sprintf("The rule is missing %d Network Gateway event(s)", [missing_count]), + } +} + +# REGLA 3: Disabled (Local) +# La regla es relevante (gateways) pero está apagada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) > 0 + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/negative1.tf b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/negative1.tf new file mode 100644 index 00000000000..9bda51072cf --- /dev/null +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/negative1.tf @@ -0,0 +1,43 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "compliant_gateway_rule" { + display_name = "CompliantGatewayRule" + compartment_id = "ocid1.tenancy.oc1..aaaa" + description = "Monitors all 15 Network Gateway events" + is_enabled = true + + condition = jsonencode({ + "eventType": [ + # Internet Gateway + "com.oraclecloud.virtualnetwork.createinternetgateway", + "com.oraclecloud.virtualnetwork.updateinternetgateway", + "com.oraclecloud.virtualnetwork.deleteinternetgateway", + # NAT Gateway + "com.oraclecloud.virtualnetwork.createnatgateway", + "com.oraclecloud.virtualnetwork.updatenatgateway", + "com.oraclecloud.virtualnetwork.deletenatgateway", + # Service Gateway + "com.oraclecloud.virtualnetwork.createservicegateway", + "com.oraclecloud.virtualnetwork.updateservicegateway", + "com.oraclecloud.virtualnetwork.deleteservicegateway", + # DRG (Dynamic Routing Gateway) + "com.oraclecloud.virtualnetwork.createdrg", + "com.oraclecloud.virtualnetwork.updatedrg", + "com.oraclecloud.virtualnetwork.deletedrg", + # LPG (Local Peering Gateway) + "com.oraclecloud.virtualnetwork.createlocalpeeringgateway", + "com.oraclecloud.virtualnetwork.updatelocalpeeringgateway", + "com.oraclecloud.virtualnetwork.deletelocalpeeringgateway" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic.oc1.iad.aaaa" + is_enabled = true + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive1.tf b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive1.tf new file mode 100644 index 00000000000..98b6d530f94 --- /dev/null +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive1.tf @@ -0,0 +1,8 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_vcn" "test_vcn" { + cidr_block = "10.0.0.0/16" + compartment_id = "ocid1.compartment..." +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive2.tf new file mode 100644 index 00000000000..00a9fbefb4e --- /dev/null +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive2.tf @@ -0,0 +1,25 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "incomplete_gateway_rule" { + display_name = "IncompleteGatewayRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + # FALLO: Solo tiene Internet Gateway, faltan los otros 12 eventos + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createinternetgateway", + "com.oraclecloud.virtualnetwork.updateinternetgateway", + "com.oraclecloud.virtualnetwork.deleteinternetgateway" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive3.tf b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive3.tf new file mode 100644 index 00000000000..82360d3d5b3 --- /dev/null +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive3.tf @@ -0,0 +1,38 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "disabled_gateway_rule" { + display_name = "DisabledGatewayRule" + compartment_id = "ocid1.tenancy..." + description = "Has all events but is disabled" + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createinternetgateway", + "com.oraclecloud.virtualnetwork.updateinternetgateway", + "com.oraclecloud.virtualnetwork.deleteinternetgateway", + "com.oraclecloud.virtualnetwork.createnatgateway", + "com.oraclecloud.virtualnetwork.updatenatgateway", + "com.oraclecloud.virtualnetwork.deletenatgateway", + "com.oraclecloud.virtualnetwork.createservicegateway", + "com.oraclecloud.virtualnetwork.updateservicegateway", + "com.oraclecloud.virtualnetwork.deleteservicegateway", + "com.oraclecloud.virtualnetwork.createdrg", + "com.oraclecloud.virtualnetwork.updatedrg", + "com.oraclecloud.virtualnetwork.deletedrg", + "com.oraclecloud.virtualnetwork.createlocalpeeringgateway", + "com.oraclecloud.virtualnetwork.updatelocalpeeringgateway", + "com.oraclecloud.virtualnetwork.deletelocalpeeringgateway" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } + + is_enabled = false +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..170738f4e34 --- /dev/null +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Event Rule for Network Gateway Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Event Rule for Network Gateway Changes is Missing", + "severity": "MEDIUM", + "line": 11, + "fileName": "positive2.tf" + }, + { + "queryName": "Event Rule for Network Gateway Changes is Missing", + "severity": "MEDIUM", + "line": 37, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/README.md b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/README.md new file mode 100644 index 00000000000..b76a8721257 --- /dev/null +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/README.md @@ -0,0 +1,44 @@ +# Regla KICS: Tópicos de Notificación con Suscripción en OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que los tópicos de notificación del servicio OCI Notifications (`oci_ons_notification_topic`) tengan al menos una suscripción (`oci_ons_subscription`) asociada. + +El servicio de notificaciones de OCI se usa para desacoplar componentes y enviar alertas. Un "tópico" es el canal al que se publican los mensajes, pero sin una "suscripción" (email, función, webhook, etc.), esos mensajes no se entregan a ningún destino y se pierden. + +## Lógica de la Regla + +La política se divide en dos reglas para cubrir los posibles escenarios de fallo: +1. **Ausencia Global:** No hay tópicos de notificación definidos. +2. **Tópico Huérfano:** Existe un tópico que no está referenciado por ninguna suscripción. + +## Casos de Fallo Detectados + +### Caso 1: Recurso `oci_ons_notification_topic` Ausente +* **Descripción:** No se encuentra ni un solo recurso de tipo `oci_ons_notification_topic` en el proyecto. +* **Ubicación de la Alerta:** Bloque `provider "oci"`. + +### Caso 2: Tópico sin Suscripciones Asociadas +* **Descripción:** Existe un recurso `oci_ons_notification_topic`, pero no existe ningún `oci_ons_subscription` cuyo `topic_id` apunte a él. +* **Ubicación de la Alerta:** Recurso `oci_ons_notification_topic`. + +## Solución + +Asegúrate de que exista al menos un tópico y que tenga una suscripción enlazada: + +```terraform +resource "oci_ons_notification_topic" "critical_alerts" { + compartment_id = var.compartment_id + name = "my-critical-alerts-topic" +} + +# RECURSO REQUERIDO: La suscripción que enlaza al tópico +resource "oci_ons_subscription" "email_subscription" { + compartment_id = var.compartment_id + + # Referencia cruzada al tópico + topic_id = oci_ons_notification_topic.critical_alerts.id + + protocol = "EMAIL" + endpoint = "ops-team@example.com" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json new file mode 100644 index 00000000000..17933e50ae3 --- /dev/null +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "8e61709a-7ba2-4d51-a8ef-796a45e7c82c", + "queryName": "Notification Topic Without Subscription", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that OCI notification topics have at least one active subscription to deliver alerts. A topic without a subscription receives messages but does not send them to any destination, rendering monitoring alerts ineffective.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/ons_subscription", + "platform": "Terraform", + "descriptionID": "8e61709a", + "cloudProvider": "oci", + "cwe": "CWE-778", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego new file mode 100644 index 00000000000..471b4476c5e --- /dev/null +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego @@ -0,0 +1,44 @@ +package Cx + +# REGLA 1: Missing (Global) +# No existe ningún recurso 'oci_ons_notification_topic' en todo el documento. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + all_topics := [topic | + topic := input.document[_].resource.oci_ons_notification_topic[_] + ] + + count(all_topics) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "At least one 'oci_ons_notification_topic' resource should exist", + "keyActualValue": "No 'oci_ons_notification_topic' resource was found", + } +} + +# REGLA 2: Orphan Topic (Local) +# Existe un tópico, pero ninguna suscripción apunta a él. +CxPolicy[result] { + doc := input.document[i] + _ := doc.resource.oci_ons_notification_topic[topic_name] + + matching_subscriptions := [sub | + sub := input.document[_].resource.oci_ons_subscription[_] + contains(sub.topic_id, topic_name) + ] + + count(matching_subscriptions) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_ons_notification_topic.%s", [topic_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'oci_ons_notification_topic' should have at least one associated 'oci_ons_subscription'", + "keyActualValue": "'oci_ons_notification_topic' has no subscriptions", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/negative1.tf b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/negative1.tf new file mode 100644 index 00000000000..85ed7f78d30 --- /dev/null +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/negative1.tf @@ -0,0 +1,16 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_ons_notification_topic" "linked_topic" { + compartment_id = "ocid1.compartment..." + name = "linked-topic" +} + +# Esta suscripción apunta correctamente al tópico de arriba +resource "oci_ons_subscription" "sub_for_linked" { + compartment_id = "ocid1.compartment..." + topic_id = oci_ons_notification_topic.linked_topic.id + protocol = "EMAIL" + endpoint = "test@example.com" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive1.tf b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive1.tf new file mode 100644 index 00000000000..d4d1b09e80c --- /dev/null +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive1.tf @@ -0,0 +1,8 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_vcn" "example_vcn" { + compartment_id = "ocid1.compartment..." + cidr_block = "10.0.0.0/16" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive2.tf b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive2.tf new file mode 100644 index 00000000000..45e44aa7f54 --- /dev/null +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive2.tf @@ -0,0 +1,9 @@ +provider "oci" { + region = "us-ashburn-1" +} + +# Caso: Tópico existe pero no tiene suscripción que lo apunte +resource "oci_ons_notification_topic" "orphan_topic" { + compartment_id = "ocid1.compartment..." + name = "orphan-topic" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive_expected_result.json new file mode 100644 index 00000000000..3cc75e994c7 --- /dev/null +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Notification Topic Without Subscription", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Notification Topic Without Subscription", + "severity": "MEDIUM", + "line": 6, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/README.md new file mode 100644 index 00000000000..e137c8f098a --- /dev/null +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/README.md @@ -0,0 +1,53 @@ +# Regla KICS: Notificación para Cambios en Grupos de Seguridad de Red (NSG) en OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio (creación, actualización o eliminación) en los Grupos de Seguridad de Red (NSG) de la cuenta de OCI. + +Los NSG proporcionan un firewall virtual para un conjunto de recursos. Un cambio no autorizado en un NSG podría exponer una aplicación a internet o permitir movimientos laterales no deseados. + +## Lógica de la Regla + +La política verifica que exista configuración activa para capturar los tres tipos de eventos críticos de NSG: +1. `com.oraclecloud.virtualnetwork.createnetworksecuritygroup` +2. `com.oraclecloud.virtualnetwork.updatenetworksecuritygroup` +3. `com.oraclecloud.virtualnetwork.deletenetworksecuritygroup` + +## Casos de Fallo Detectados + +### Caso 1: Regla Ausente (Missing) +* **Descripción:** No existe ninguna regla configurada para NSGs en el proyecto. +* **Ubicación de la Alerta:** Bloque `provider "oci"`. + +### Caso 2: Regla Incompleta (Incomplete) +* **Descripción:** Existe una regla para NSGs, pero le faltan eventos (ej. monitoriza create pero olvida delete). +* **Ubicación de la Alerta:** Atributo `condition`. + +### Caso 3: Regla Deshabilitada (Disabled) +* **Descripción:** Existe una regla relevante pero está explícitamente deshabilitada (`is_enabled = false`). +* **Ubicación de la Alerta:** Atributo `is_enabled` dentro del recurso. + +## Solución + +```terraform +resource "oci_events_rule" "nsg_change_rule" { + display_name = "audit-rule-for-nsg-changes" + description = "Alerts on any creation, update, or deletion of Network Security Groups" + compartment_id = var.tenancy_ocid + is_enabled = true + + condition = jsonencode({ + eventType = [ + "com.oraclecloud.virtualnetwork.createnetworksecuritygroup", + "com.oraclecloud.virtualnetwork.updatenetworksecuritygroup", + "com.oraclecloud.virtualnetwork.deletenetworksecuritygroup" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = oci_ons_notification_topic.security_alerts_topic.id + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json new file mode 100644 index 00000000000..f6523663741 --- /dev/null +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "a1b080a7-8d58-4018-a14d-17beb72f5cef", + "queryName": "Event Rule for NSG Changes is Missing", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Network Security Groups (NSGs). Auditing changes to NSGs is critical for detecting unauthorized modifications to network micro-segmentation rules that could expose services.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "a1b080a7", + "cloudProvider": "oci", + "cwe": "CWE-778", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego new file mode 100644 index 00000000000..79295221afb --- /dev/null +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego @@ -0,0 +1,76 @@ +package Cx + +expected_event_types := [ + "com.oraclecloud.virtualnetwork.createnetworksecuritygroup", + "com.oraclecloud.virtualnetwork.updatenetworksecuritygroup", + "com.oraclecloud.virtualnetwork.deletenetworksecuritygroup" +] + +# REGLA 1: Missing (Global) +# No existe NINGUNA regla en el proyecto que monitoree NSGs. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_nsg_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_nsg_rule) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for Network Security Group changes should exist", + "keyActualValue": "No 'oci_events_rule' found for Network Security Group changes", + } +} + +# REGLA 2: Incomplete (Local) +# La regla existe, pero le faltan eventos (ej: tiene create pero falta delete). +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 3 NSG events (create, update, delete)", + "keyActualValue": sprintf("The rule is missing %d NSG event(s)", [missing_count]), + } +} + +# REGLA 3: Disabled (Local) +# La regla es relevante (NSG) pero está apagada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) > 0 + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/negative1.tf b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/negative1.tf new file mode 100644 index 00000000000..520332272d4 --- /dev/null +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/negative1.tf @@ -0,0 +1,25 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "correct_nsg_rule" { + display_name = "CorrectNSGRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createnetworksecuritygroup", + "com.oraclecloud.virtualnetwork.updatenetworksecuritygroup", + "com.oraclecloud.virtualnetwork.deletenetworksecuritygroup" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + is_enabled = true + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive1.tf b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive1.tf new file mode 100644 index 00000000000..7df264f33a7 --- /dev/null +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive1.tf @@ -0,0 +1,9 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_network_security_group" "test_nsg" { + compartment_id = "ocid1.compartment..." + display_name = "test-nsg" + vcn_id = "ocid1.vcn..." +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive2.tf new file mode 100644 index 00000000000..ecf21db2ea8 --- /dev/null +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive2.tf @@ -0,0 +1,24 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "incomplete_nsg_rule" { + display_name = "IncompleteNSGRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + # FALLO: Falta "deletenetworksecuritygroup" + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createnetworksecuritygroup", + "com.oraclecloud.virtualnetwork.updatenetworksecuritygroup" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive3.tf b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive3.tf new file mode 100644 index 00000000000..2923fcaf250 --- /dev/null +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive3.tf @@ -0,0 +1,26 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "disabled_nsg_rule" { + display_name = "DisabledNSGRule" + compartment_id = "ocid1.tenancy..." + description = "Has all events but is disabled" + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createnetworksecuritygroup", + "com.oraclecloud.virtualnetwork.updatenetworksecuritygroup", + "com.oraclecloud.virtualnetwork.deletenetworksecuritygroup" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } + + is_enabled = false +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..9eedb1c4941 --- /dev/null +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Event Rule for NSG Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Event Rule for NSG Changes is Missing", + "severity": "MEDIUM", + "line": 11, + "fileName": "positive2.tf" + }, + { + "queryName": "Event Rule for NSG Changes is Missing", + "severity": "MEDIUM", + "line": 25, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/README.md b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/README.md new file mode 100644 index 00000000000..8fe00ec4c3b --- /dev/null +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/README.md @@ -0,0 +1,34 @@ +# Regla KICS: Logging de Escritura en OCI Object Storage + +## Descripción General + +Esta regla de KICS para Terraform asegura que todos los buckets de OCI Object Storage (`oci_objectstorage_bucket`) tengan habilitada la emisión de eventos para objetos. Esta funcionalidad es fundamental para el logging de operaciones de escritura, como la creación (`put`), sobreescritura y eliminación de objetos. + +Auditar quién modifica o elimina datos es un requisito de seguridad y cumplimiento normativo crítico. Esta política verifica los dos escenarios posibles de mala configuración para proporcionar alertas precisas. + +## Lógica de la Regla + +La política se compone de dos reglas especializadas que cubren todos los casos en los que el logging de eventos de objeto está desactivado. + +## Casos de Fallo Detectados + +### Caso 1: Atributo `object_events_enabled` Ausente + +* **Descripción:** Esta regla detecta cualquier recurso `oci_objectstorage_bucket` donde el atributo `object_events_enabled` no está definido. El valor por defecto es `false`. +* **Ubicación de la Alerta:** Recurso `oci_objectstorage_bucket`. + +### Caso 2: Atributo `object_events_enabled` es `false` + +* **Descripción:** Esta regla busca un recurso `oci_objectstorage_bucket` que tiene el atributo `object_events_enabled` explícitamente configurado como `false`. +* **Ubicación de la Alerta:** Atributo `object_events_enabled`. + +## Solución + +Para solucionar los problemas detectados por esta regla, asegúrate de que cada recurso `oci_objectstorage_bucket` incluya la siguiente línea: + +```terraform +resource "oci_objectstorage_bucket" "example" { + # ... otros atributos ... + + object_events_enabled = true +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json new file mode 100644 index 00000000000..cb41f1a3af0 --- /dev/null +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "5ecf7b51-8c4b-4911-9d59-1f7f6b9a2143", + "queryName": "Object Storage Bucket Logging Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that OCI Object Storage buckets have object event emission enabled, which is crucial for write-level logging and security auditing.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/objectstorage_bucket#object_events_enabled", + "platform": "Terraform", + "descriptionID": "5ecf7b51", + "cloudProvider": "oci", + "cwe": "CWE-223", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/query.rego b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/query.rego new file mode 100644 index 00000000000..8a11d86be3d --- /dev/null +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/query.rego @@ -0,0 +1,32 @@ +package Cx + +# REGLA 1: El atributo 'object_events_enabled' está ausente (MissingAttribute). +# Por defecto en OCI Terraform es false, así que su ausencia es un riesgo. +CxPolicy[result] { + bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] + + object.get(bucket, "object_events_enabled", null) == null + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_objectstorage_bucket.%s", [bucket_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'object_events_enabled' should be present and set to 'true'", + "keyActualValue": "'object_events_enabled' is missing and defaults to 'false'", + } +} + +# REGLA 2: El atributo 'object_events_enabled' está explícitamente en 'false' (IncorrectValue). +CxPolicy[result] { + bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] + + bucket.object_events_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_objectstorage_bucket.%s.object_events_enabled", [bucket_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'object_events_enabled' attribute should be 'true'", + "keyActualValue": "'object_events_enabled' attribute is 'false'", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/negative1.tf b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/negative1.tf new file mode 100644 index 00000000000..dcb5c904ef2 --- /dev/null +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/negative1.tf @@ -0,0 +1,12 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_objectstorage_bucket" "bucket_enabled_log" { + compartment_id = "ocid1.compartment.oc1..aaaa" + namespace = "my-namespace" + name = "bucket-secure" + + # CORRECTO + object_events_enabled = true +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive1.tf b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive1.tf new file mode 100644 index 00000000000..3e1a2bfe185 --- /dev/null +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive1.tf @@ -0,0 +1,11 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_objectstorage_bucket" "bucket_missing_log" { + compartment_id = "ocid1.compartment.oc1..aaaa" + namespace = "my-namespace" + name = "bucket-no-logs" + access_type = "NoPublicAccess" + # FALLO: Falta object_events_enabled +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive2.tf b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive2.tf new file mode 100644 index 00000000000..bac22f14e63 --- /dev/null +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive2.tf @@ -0,0 +1,12 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_objectstorage_bucket" "bucket_disabled_log" { + compartment_id = "ocid1.compartment.oc1..aaaa" + namespace = "my-namespace" + name = "bucket-disabled-logs" + + # FALLO: Explícitamente false + object_events_enabled = false +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive_expected_result.json new file mode 100644 index 00000000000..92add310abf --- /dev/null +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Object Storage Bucket Logging Disabled", + "severity": "MEDIUM", + "line": 5, + "fileName": "positive1.tf" + }, + { + "queryName": "Object Storage Bucket Logging Disabled", + "severity": "MEDIUM", + "line": 11, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/README.md b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/README.md new file mode 100644 index 00000000000..e356a9823d2 --- /dev/null +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/README.md @@ -0,0 +1,34 @@ +# Regla KICS: Versionado Habilitado para Buckets de Object Storage en OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que todos los buckets de OCI Object Storage (`oci_objectstorage_bucket`) tengan habilitada la funcionalidad de versionado. + +El versionado es una capa de protección de datos fundamental. Cuando está habilitado, cualquier modificación (sobrescritura) o eliminación de un objeto no lo destruye permanentemente, sino que crea una nueva versión o un marcador de eliminación. Esto permite recuperar fácilmente versiones anteriores de un objeto en caso de un borrado accidental o una modificación no deseada, actuando como una red de seguridad contra la pérdida de datos. + +## Lógica de la Regla + +La política se compone de dos reglas para cubrir los escenarios en los que el versionado está desactivado, centradas en el atributo `versioning`. + +## Casos de Fallo Detectados + +### Caso 1: Atributo `versioning` Ausente + +* **Descripción:** Esta regla detecta cualquier recurso `oci_objectstorage_bucket` donde el atributo `versioning` no está definido. Si se omite, el versionado no se habilita por defecto. +* **Ubicación de la Alerta:** Recurso `oci_objectstorage_bucket`. + +### Caso 2: Atributo `versioning` no es `Enabled` + +* **Descripción:** Esta regla busca un recurso `oci_objectstorage_bucket` que tiene el atributo `versioning` explícitamente configurado con un valor diferente a `"Enabled"` (por ejemplo, `"Suspended"` o `"Disabled"`). +* **Ubicación de la Alerta:** Atributo `versioning`. + +## Solución + +Para solucionar los problemas detectados, asegúrate de que cada recurso `oci_objectstorage_bucket` incluya el atributo `versioning` con el valor `"Enabled"`. + +```terraform +resource "oci_objectstorage_bucket" "example" { + # ... otros atributos ... + + versioning = "Enabled" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json new file mode 100644 index 00000000000..600bcac7475 --- /dev/null +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "72b1c53c-619e-4e0a-937a-9af24cae69df", + "queryName": "Object Storage Bucket Versioning Disabled", + "severity": "MEDIUM", + "category": "Data Security", + "descriptionText": "Ensures that OCI Object Storage buckets have versioning enabled. Versioning protects against accidental deletion or overwriting of objects by keeping a history of all object versions.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/objectstorage_bucket#versioning", + "platform": "Terraform", + "descriptionID": "72b1c53c", + "cloudProvider": "oci", + "cwe": "CWE-668", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/query.rego b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/query.rego new file mode 100644 index 00000000000..e280e479a55 --- /dev/null +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/query.rego @@ -0,0 +1,34 @@ +package Cx + +# REGLA 1: El atributo 'versioning' está ausente en el bucket. +# Por defecto, si no se especifica, el versionado está deshabilitado. +CxPolicy[result] { + bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] + + object.get(bucket, "versioning", null) == null + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_objectstorage_bucket.%s", [bucket_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'versioning' attribute should be present and set to 'Enabled'", + "keyActualValue": "'versioning' attribute is missing, disabling versioning", + } +} + +# REGLA 2: El atributo 'versioning' existe pero no es 'Enabled'. +# Puede ser 'Disabled' o 'Suspended'. +CxPolicy[result] { + bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] + + object.get(bucket, "versioning", null) != null + bucket.versioning != "Enabled" + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_objectstorage_bucket.%s.versioning", [bucket_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'versioning' attribute should be 'Enabled'", + "keyActualValue": sprintf("'versioning' attribute is '%s'", [bucket.versioning]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/negative1.tf b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/negative1.tf new file mode 100644 index 00000000000..466b92b441c --- /dev/null +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/negative1.tf @@ -0,0 +1,12 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_objectstorage_bucket" "bucket_enabled_versioning" { + compartment_id = "ocid1.compartment.oc1..aaaa" + namespace = "my-namespace" + name = "bucket-secure" + + # CORRECTO + versioning = "Enabled" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive1.tf b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive1.tf new file mode 100644 index 00000000000..a23885af982 --- /dev/null +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive1.tf @@ -0,0 +1,11 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_objectstorage_bucket" "bucket_missing_versioning" { + compartment_id = "ocid1.compartment.oc1..aaaa" + namespace = "my-namespace" + name = "bucket-no-ver" + access_type = "NoPublicAccess" + # FALLO: Falta el atributo versioning +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive2.tf b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive2.tf new file mode 100644 index 00000000000..7730d44e087 --- /dev/null +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive2.tf @@ -0,0 +1,12 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_objectstorage_bucket" "bucket_suspended_versioning" { + compartment_id = "ocid1.compartment.oc1..aaaa" + namespace = "my-namespace" + name = "bucket-suspended" + + # FALLO: Está suspendido + versioning = "Suspended" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..6e91b54c4a4 --- /dev/null +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Object Storage Bucket Versioning Disabled", + "severity": "MEDIUM", + "line": 5, + "fileName": "positive1.tf" + }, + { + "queryName": "Object Storage Bucket Versioning Disabled", + "severity": "MEDIUM", + "line": 11, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/README.md b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/README.md new file mode 100644 index 00000000000..e9d61f3d55d --- /dev/null +++ b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/README.md @@ -0,0 +1,35 @@ +# Regla KICS: Recursos Creados Fuera del Compartimento Raíz en OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que los recursos no se creen directamente en el compartimento raíz (también conocido como *tenancy*). + +El compartimento raíz tiene los máximos privilegios y debe mantenerse lo más limpio posible, conteniendo únicamente otros compartimentos y políticas de IAM a nivel de *tenancy*. Crear recursos operativos (como instancias de cómputo, redes virtuales o bases de datos) en el compartimento raíz viola los principios de **menor privilegio**. + +## Lógica de la Regla + +La política mantiene una lista interna de tipos de recursos auditables. Itera sobre todos los recursos definidos en la configuración de Terraform y, si un recurso es de un tipo auditable, verifica el valor de su `compartment_id`. + +La regla se activa si el `compartment_id` apunta al compartimento raíz. Esto se detecta de dos maneras: +1. Si el valor es una referencia a `var.tenancy_ocid`. +2. Si el propio valor del OCID contiene la palabra `tenancy` (case-insensitive). + +## Caso de Fallo Detectado + +### Caso Único: Recurso con `compartment_id` apuntando al Raíz +* **Descripción:** Un recurso de la lista auditable tiene su `compartment_id` asignado al OCID del *tenancy*. +* **Ubicación de la Alerta:** Atributo `compartment_id`. + +## Solución + +Asegúrate de que todos los recursos se creen en compartimentos hijos apropiados. + +```terraform +variable "networking_compartment_ocid" {} + +# Esta VCN se crea en un compartimento hijo dedicado, lo cual es correcto. +resource "oci_core_vcn" "example_vcn_correct" { + compartment_id = var.networking_compartment_ocid + display_name = "VcnInNetworkingCompartment" + cidr_block = "10.1.0.0/16" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json new file mode 100644 index 00000000000..c568020e617 --- /dev/null +++ b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "eb205044-d89b-40ac-9846-2e5993e091ab", + "queryName": "Resource Created In Root Compartment", + "severity": "HIGH", + "category": "Best Practices", + "descriptionText": "Ensures that resources are not created directly in the root compartment (tenancy). Following the principle of least privilege and separation of concerns, resources should be organized into dedicated child compartments.", + "descriptionUrl": "https://docs.oracle.com/en-us/iaas/Content/cloud-adoption-framework/iam-security-structure.htm", + "platform": "Terraform", + "descriptionID": "eb205044", + "cloudProvider": "oci", + "cwe": "CWE-284", + "riskScore": 6.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/query.rego b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/query.rego new file mode 100644 index 00000000000..10acdb2003a --- /dev/null +++ b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/query.rego @@ -0,0 +1,52 @@ +package Cx + +import future.keywords.in + +auditable_resource_types := { + "oci_core_instance", + "oci_core_vcn", + "oci_core_subnet", + "oci_core_security_list", + "oci_core_route_table", + "oci_core_internet_gateway", + "oci_core_nat_gateway", + "oci_core_service_gateway", + "oci_objectstorage_bucket", + "oci_database_db_system", + "oci_containerengine_cluster", + "oci_functions_application", + "oci_kms_vault", + "oci_ons_notification_topic" +} + +is_root_compartment(compartment_id) { + contains(lower(compartment_id), "var.tenancy_ocid") +} +is_root_compartment(compartment_id) { + contains(lower(compartment_id), "tenancy") +} + +CxPolicy[result] { + doc := input.document[i] + + some resource_type + resources := doc.resource[resource_type] + + resource_type in auditable_resource_types + + some resource_name + resource := resources[resource_name] + + compartment_id := object.get(resource, "compartment_id", "") + compartment_id != "" + + is_root_compartment(compartment_id) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.%s.%s.compartment_id", [resource_type, resource_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": sprintf("Resource '%s' should be created in a child compartment, not the root compartment", [resource_name]), + "keyActualValue": sprintf("Resource '%s' is created in the root compartment (tenancy)", [resource_name]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/negative1.tf b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/negative1.tf new file mode 100644 index 00000000000..94e3a98c1c7 --- /dev/null +++ b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/negative1.tf @@ -0,0 +1,17 @@ +provider "oci" { + region = "us-ashburn-1" +} + +variable "network_cmp_id" {} + +resource "oci_core_vcn" "child_vcn" { + cidr_block = "10.0.0.0/16" + compartment_id = var.network_cmp_id + display_name = "ChildVCN" +} + +resource "oci_objectstorage_bucket" "child_bucket" { + namespace = "ns" + name = "child-bucket" + compartment_id = "ocid1.compartment.oc1..bbbb..." +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive1.tf b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive1.tf new file mode 100644 index 00000000000..1baa92902ff --- /dev/null +++ b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive1.tf @@ -0,0 +1,12 @@ +provider "oci" { + region = "us-ashburn-1" +} + +variable "tenancy_ocid" {} + +# Caso: Uso explícito de var.tenancy_ocid +resource "oci_core_vcn" "root_vcn" { + cidr_block = "10.0.0.0/16" + compartment_id = var.tenancy_ocid + display_name = "RootVCN" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive2.tf b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive2.tf new file mode 100644 index 00000000000..37e4bc75290 --- /dev/null +++ b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive2.tf @@ -0,0 +1,10 @@ +provider "oci" { + region = "us-ashburn-1" +} + +# Caso: OCID hardcoded que contiene 'tenancy' +resource "oci_objectstorage_bucket" "root_bucket" { + namespace = "ns" + name = "root-bucket" + compartment_id = "ocid1.tenancy.oc1..aaaa..." +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive_expected_result.json new file mode 100644 index 00000000000..3d6d6db9c73 --- /dev/null +++ b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "Resource Created In Root Compartment", + "severity": "HIGH", + "line": 10, + "fileName": "positive1.tf" + }, + { + "queryName": "Resource Created In Root Compartment", + "severity": "HIGH", + "line": 9, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/README.md new file mode 100644 index 00000000000..bd96ad8138f --- /dev/null +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/README.md @@ -0,0 +1,53 @@ +# Regla KICS: Notificación para Cambios en Tablas de Enrutamiento en OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio (creación, actualización o eliminación) en las Tablas de Enrutamiento (Route Tables) de la cuenta de OCI. + +Las tablas de enrutamiento controlan el flujo del tráfico de red entre subredes . Un cambio no autorizado podría redirigir el tráfico maliciosamente. + +## Lógica de la Regla + +La política verifica que exista configuración activa para capturar los tres tipos de eventos críticos de Route Tables: +1. `com.oraclecloud.virtualnetwork.createroutetable` +2. `com.oraclecloud.virtualnetwork.updateroutetable` +3. `com.oraclecloud.virtualnetwork.deleteroutetable` + +## Casos de Fallo Detectados + +### Caso 1: Regla Ausente (Missing) +* **Descripción:** No existe ninguna regla configurada para Route Tables en el proyecto. +* **Ubicación de la Alerta:** Bloque `provider "oci"`. + +### Caso 2: Regla Incompleta (Incomplete) +* **Descripción:** Existe una regla para Route Tables, pero le faltan eventos (ej. monitoriza create pero olvida delete). +* **Ubicación de la Alerta:** Atributo `condition`. + +### Caso 3: Regla Deshabilitada (Disabled) +* **Descripción:** Existe una regla relevante pero está explícitamente deshabilitada (`is_enabled = false`). +* **Ubicación de la Alerta:** Atributo `is_enabled` dentro del recurso. + +## Solución + +```terraform +resource "oci_events_rule" "route_table_change_rule" { + display_name = "audit-rule-for-route-table-changes" + description = "Alerts on any creation, update, or deletion of Route Tables" + compartment_id = var.tenancy_ocid + is_enabled = true + + condition = jsonencode({ + eventType = [ + "com.oraclecloud.virtualnetwork.createroutetable", + "com.oraclecloud.virtualnetwork.updateroutetable", + "com.oraclecloud.virtualnetwork.deleteroutetable" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = oci_ons_notification_topic.security_alerts_topic.id + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json new file mode 100644 index 00000000000..81c3ef62cf8 --- /dev/null +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "b3af1ce8-5711-4304-b1db-17b658629df2", + "queryName": "Event Rule for Route Table Changes is Missing", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Route Tables. Auditing changes to route tables is critical for detecting unauthorized network path modifications that could lead to traffic interception or service disruption.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "b3af1ce8", + "cloudProvider": "oci", + "cwe": "CWE-778", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego new file mode 100644 index 00000000000..78c6bc27730 --- /dev/null +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego @@ -0,0 +1,76 @@ +package Cx + +expected_event_types := [ + "com.oraclecloud.virtualnetwork.createroutetable", + "com.oraclecloud.virtualnetwork.updateroutetable", + "com.oraclecloud.virtualnetwork.deleteroutetable" +] + +# REGLA 1: Missing (Global) +# No existe NINGUNA regla en el proyecto que monitoree Route Tables. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_rt_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_rt_rule) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for Route Table changes should exist", + "keyActualValue": "No 'oci_events_rule' found for Route Table changes", + } +} + +# REGLA 2: Incomplete (Local) +# La regla existe, pero le faltan eventos (ej: tiene create pero falta update). +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 3 Route Table events (create, update, delete)", + "keyActualValue": sprintf("The rule is missing %d Route Table event(s)", [missing_count]), + } +} + +# REGLA 3: Disabled (Local) +# La regla es relevante (Route Table) pero está apagada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) > 0 + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/negative1.tf b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/negative1.tf new file mode 100644 index 00000000000..573e9e52a2a --- /dev/null +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/negative1.tf @@ -0,0 +1,25 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "correct_rt_rule" { + display_name = "CorrectRTRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createroutetable", + "com.oraclecloud.virtualnetwork.updateroutetable", + "com.oraclecloud.virtualnetwork.deleteroutetable" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + is_enabled = true + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive1.tf b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive1.tf new file mode 100644 index 00000000000..ebf9915565f --- /dev/null +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive1.tf @@ -0,0 +1,9 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_route_table" "test_rt" { + compartment_id = "ocid1.compartment..." + vcn_id = "ocid1.vcn..." + display_name = "test-rt" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive2.tf new file mode 100644 index 00000000000..74025ee37c7 --- /dev/null +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive2.tf @@ -0,0 +1,24 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "incomplete_rt_rule" { + display_name = "IncompleteRTRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + # FALLO: Falta "deleteroutetable" + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createroutetable", + "com.oraclecloud.virtualnetwork.updateroutetable" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive3.tf b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive3.tf new file mode 100644 index 00000000000..9e99b4f636b --- /dev/null +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive3.tf @@ -0,0 +1,26 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "disabled_rt_rule" { + display_name = "DisabledRTRule" + compartment_id = "ocid1.tenancy..." + description = "Has all events but is disabled" + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createroutetable", + "com.oraclecloud.virtualnetwork.updateroutetable", + "com.oraclecloud.virtualnetwork.deleteroutetable" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } + + is_enabled = false +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..d4502f2e88f --- /dev/null +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Event Rule for Route Table Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Event Rule for Route Table Changes is Missing", + "severity": "MEDIUM", + "line": 11, + "fileName": "positive2.tf" + }, + { + "queryName": "Event Rule for Route Table Changes is Missing", + "severity": "MEDIUM", + "line": 25, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/README.md new file mode 100644 index 00000000000..5aeef264100 --- /dev/null +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/README.md @@ -0,0 +1,54 @@ +# Regla KICS: Notificación para Cambios en Listas de Seguridad en OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio (creación, actualización o eliminación) en las Listas de Seguridad (Security Lists) de la cuenta de OCI. + +Las Listas de Seguridad actúan como un firewall virtual a nivel de subred. Un cambio no autorizado, como añadir una regla que permita el acceso desde cualquier IP (`0.0.0.0/0`) a un puerto de gestión, puede exponer gravemente la infraestructura. + +## Lógica de la Regla + +La política verifica la configuración de los recursos `oci_events_rule` buscando los tres tipos de eventos fundamentales: +* `com.oraclecloud.virtualnetwork.createsecuritylist` +* `com.oraclecloud.virtualnetwork.updatesecuritylist` +* `com.oraclecloud.virtualnetwork.deletesecuritylist` + +## Casos de Fallo Detectados + +### Caso 1: Regla Ausente (Missing) +* **Descripción:** No existe ninguna regla en la configuración que monitorice cambios en Security Lists. +* **Ubicación:** Bloque `provider "oci"`. + +### Caso 2: Regla Incompleta (Incomplete) +* **Descripción:** Existe una regla pero no incluye los tres eventos requeridos (create, update, delete). +* **Ubicación:** Atributo `condition`. + +### Caso 3: Regla Deshabilitada (Disabled) +* **Descripción:** Existe una regla relevante pero el atributo `is_enabled` es `false`. +* **Ubicación:** Atributo `is_enabled`. + +## Solución + +Asegúrate de incluir una regla habilitada con los eventos correspondientes: + +```terraform +resource "oci_events_rule" "security_list_change_rule" { + display_name = "audit-rule-for-security-list-changes" + compartment_id = var.tenancy_ocid + is_enabled = true + + condition = jsonencode({ + eventType = [ + "com.oraclecloud.virtualnetwork.createsecuritylist", + "com.oraclecloud.virtualnetwork.updatesecuritylist", + "com.oraclecloud.virtualnetwork.deletesecuritylist" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = oci_ons_notification_topic.security_alerts_topic.id + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json new file mode 100644 index 00000000000..2a6684d23b6 --- /dev/null +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "a5dfa109-1f7d-4077-8d10-41247bfcf922", + "queryName": "Event Rule for Security List Changes is Missing", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Security Lists. Auditing changes to these network ACLs is critical for detecting unauthorized modifications that could expose services to unintended traffic.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "a5dfa109", + "cloudProvider": "oci", + "cwe": "CWE-778", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego new file mode 100644 index 00000000000..13db46a0e07 --- /dev/null +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego @@ -0,0 +1,75 @@ +package Cx + +expected_event_types := [ + "com.oraclecloud.virtualnetwork.createsecuritylist", + "com.oraclecloud.virtualnetwork.updatesecuritylist", + "com.oraclecloud.virtualnetwork.deletesecuritylist" +] + +# REGLA 1: Missing (Global) +# No existe ninguna regla en el proyecto que monitoree Security Lists. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_sl_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_sl_rule) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for Security List changes should exist", + "keyActualValue": "No 'oci_events_rule' found for Security List changes", + } +} + +# REGLA 2: Incomplete (Local) +# La regla existe pero le faltan eventos (ej: tiene create pero falta delete). +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 3 Security List events (create, update, delete)", + "keyActualValue": sprintf("The rule is missing %d Security List event(s)", [missing_count]), + } +} + +# REGLA 3: Disabled (Local) +# La regla es relevante para Security Lists pero está apagada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) > 0 + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/negative1.tf b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/negative1.tf new file mode 100644 index 00000000000..f4b702e0533 --- /dev/null +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/negative1.tf @@ -0,0 +1,24 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "compliant_sl_rule" { + display_name = "CompliantSLRule" + compartment_id = "ocid1.tenancy.oc1..aaaa" + is_enabled = true + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createsecuritylist", + "com.oraclecloud.virtualnetwork.updatesecuritylist", + "com.oraclecloud.virtualnetwork.deletesecuritylist" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic.oc1..aaaa" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive1.tf b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive1.tf new file mode 100644 index 00000000000..1183f90ad37 --- /dev/null +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive1.tf @@ -0,0 +1,9 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_security_list" "test_sl" { + compartment_id = "ocid1.compartment.oc1..aaaa" + vcn_id = "ocid1.vcn.oc1..aaaa" + display_name = "vulnerable_sl" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive2.tf new file mode 100644 index 00000000000..3af0e42cc84 --- /dev/null +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive2.tf @@ -0,0 +1,23 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "incomplete_sl_rule" { + display_name = "IncompleteSLRule" + compartment_id = "ocid1.tenancy.oc1..aaaa" + is_enabled = true + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createsecuritylist", + "com.oraclecloud.virtualnetwork.updatesecuritylist" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic.oc1..aaaa" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive3.tf b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive3.tf new file mode 100644 index 00000000000..82e7e8390ac --- /dev/null +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive3.tf @@ -0,0 +1,25 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "disabled_sl_rule" { + display_name = "DisabledSLRule" + compartment_id = "ocid1.tenancy.oc1..aaaa" + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createsecuritylist", + "com.oraclecloud.virtualnetwork.updatesecuritylist", + "com.oraclecloud.virtualnetwork.deletesecuritylist" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic.oc1..aaaa" + } + } + + is_enabled = false +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..7b344cdf4f9 --- /dev/null +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Event Rule for Security List Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Event Rule for Security List Changes is Missing", + "severity": "MEDIUM", + "line": 10, + "fileName": "positive2.tf" + }, + { + "queryName": "Event Rule for Security List Changes is Missing", + "severity": "MEDIUM", + "line": 24, + "fileName": "positive3.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/README.md b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/README.md new file mode 100644 index 00000000000..63a02d7b3d2 --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/README.md @@ -0,0 +1,40 @@ +# Regla KICS: OCI Storage Admin with Delete Privileges (Manual) + +## Descripción General + +Esta regla informativa (INFO) audita las políticas de IAM (`oci_identity_policy`) para identificar administradores de almacenamiento con permisos excesivos, específicamente la capacidad de borrar recursos. + +En OCI, el verbo **`manage`** incluye todos los permisos: `inspect`, `read`, `use`, `create`, `update` y **`DELETE`**. Para cumplir con controles estrictos de protección de datos, los administradores de almacenamiento no deberían tener capacidad para eliminar volúmenes o buckets por defecto, o esta capacidad debería estar restringida mediante condiciones. + +## Lógica de la Regla + +1. Analiza las sentencias (`statements`) de las políticas. +2. Busca la combinación del verbo exacto `manage` con familias de almacenamiento: + * `object-family` + * `volume-family` + * `file-family` + * `autonomous-database-family` +3. Genera una alerta INFO para revisión manual si se detecta acceso total de gestión. + +## Casos de Fallo Detectados + +### Caso 1: Gestión Total de Almacenamiento +* **Descripción:** Se otorga `manage` sobre una familia de almacenamiento sin restricciones visibles en la sentencia. +* **Acción:** Verificar si el usuario realmente requiere capacidad de borrado o si se puede añadir una cláusula `where request.permission != 'DELETE'`. + +## Recursos Involucrados +* `oci_identity_policy` + +## Solución + +Añade una condición a la política para restringir el borrado. + +```terraform +resource "oci_identity_policy" "storage_admin_safe" { + name = "SafeStorageAdmin" + compartment_id = var.tenancy_ocid + statements = [ + # Permite gestionar todo EXCEPTO borrar + "Allow group StorageAdmins to manage object-family in tenancy where request.permission != 'DELETE'" + ] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/metadata.json b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/metadata.json new file mode 100644 index 00000000000..2ea719539c7 --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "8cd7b5db-800b-4c93-949b-bc215d63f7c3", + "queryName": "OCI Storage Admin with Delete Privileges (Manual)", + "severity": "INFO", + "category": "Identity and Access Management", + "descriptionText": "Storage service-level admins should ideally not have 'DELETE' permissions to prevent accidental or malicious data loss. The verb 'manage' includes DELETE permissions by default. Verify if a condition 'where request.permission != DELETE' is applied or if the 'manage' verb is necessary.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/identity_policy", + "platform": "Terraform", + "descriptionID": "8cd7b5db", + "cloudProvider": "oci", + "cwe": "CWE-269", + "riskScore": 0.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/query.rego b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/query.rego new file mode 100644 index 00000000000..429152d2fe1 --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/query.rego @@ -0,0 +1,29 @@ +package Cx + +storage_families := { + "object-family", + "volume-family", + "file-family", + "autonomous-database-family" +} + +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.oci_identity_policy[name] + + statement := policy.statements[_] + statement_lower := lower(statement) + + regex.match("(?i)\\bmanage\\b", statement) + + family := storage_families[_] + contains(statement_lower, family) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_policy.%s.statements", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": sprintf("Statement granting 'manage' on '%s' should ideally exclude DELETE permissions via 'where request.permission != DELETE'", [family]), + "keyActualValue": sprintf("Statement grants full 'manage' access (including DELETE) on '%s': '%s'", [family, statement]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative1.tf b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative1.tf new file mode 100644 index 00000000000..907698d9916 --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative1.tf @@ -0,0 +1,13 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_policy" "read_only_storage" { + name = "ReadOnlyStorage" + compartment_id = "ocid1.tenancy..." + + # CORRECTO: El verbo es read, no incluye delete + statements = [ + "Allow group Auditors to read object-family in tenancy" + ] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative2.tf b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative2.tf new file mode 100644 index 00000000000..74f3d0745ba --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative2.tf @@ -0,0 +1,13 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_policy" "false_positive_check" { + name = "ManagerCheck" + compartment_id = "ocid1.tenancy..." + + # CORRECTO: Aunque el grupo se llama Managers, el verbo es read. El regex \bmanage\b evita el fallo. + statements = [ + "Allow group ObjectManagers to read object-family in tenancy" + ] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive1.tf b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive1.tf new file mode 100644 index 00000000000..4ea3bcac30a --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive1.tf @@ -0,0 +1,13 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_policy" "unsafe_object_admin" { + name = "UnsafeObjectAdmin" + compartment_id = "ocid1.tenancy..." + + # FALLO: Otorga manage (incluye delete) en object-family + statements = [ + "Allow group StorageAdmins to manage object-family in tenancy" + ] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive2.tf b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive2.tf new file mode 100644 index 00000000000..4f5f8234695 --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive2.tf @@ -0,0 +1,13 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_policy" "unsafe_volume_admin" { + name = "UnsafeVolumeAdmin" + compartment_id = "ocid1.tenancy..." + + # FALLO: Otorga manage (incluye delete) en volume-family + statements = [ + "Allow group BackupAdmins to MANAGE volume-family in tenancy" + ] +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive_expected_result.json new file mode 100644 index 00000000000..e4a32105d59 --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "OCI Storage Admin with Delete Privileges (Manual)", + "severity": "INFO", + "line": 10, + "fileName": "positive1.tf" + }, + { + "queryName": "OCI Storage Admin with Delete Privileges (Manual)", + "severity": "INFO", + "line": 10, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/README.md b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/README.md new file mode 100644 index 00000000000..175b79913f5 --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/README.md @@ -0,0 +1,40 @@ +# Regla KICS: OCI Storage Resources Without CMK + +## Descripción General + +Esta regla unificada de severidad **MEDIA** audita los recursos de almacenamiento de OCI para asegurar que utilicen claves gestionadas por el cliente (CMK). + +Aunque OCI cifra los datos en reposo por defecto, lo hace con claves gestionadas por Oracle. Para tener control total sobre el ciclo de vida de la clave (rotación, revocación), es necesario asignar una clave de **OCI Vault** mediante el atributo `kms_key_id`. + +## Lógica de la Regla + +La política verifica los siguientes recursos: +* `oci_objectstorage_bucket` +* `oci_core_volume` +* `oci_core_boot_volume` +* `oci_file_storage_file_system` + +La regla se activa si: +1. El atributo `kms_key_id` no está definido. +2. El atributo `kms_key_id` está presente pero tiene un valor vacío. + +## Casos de Fallo Detectados + +### Caso 1: Cifrado por Defecto (Oracle-Managed) +* **Descripción:** El recurso no define `kms_key_id`, delegando el control de la clave a Oracle. +* **Ubicación de la Alerta:** Bloque del recurso. + +### Caso 2: Configuración Vacía +* **Descripción:** Se define el atributo pero no se proporciona un OCID válido. +* **Ubicación de la Alerta:** Atributo `kms_key_id`. + +## Solución + +Asigna el OCID de una clave de OCI Vault al recurso. + +```terraform +resource "oci_objectstorage_bucket" "secure_bucket" { + name = "secure-bucket" + compartment_id = var.compartment_id + kms_key_id = "ocid1.key.oc1.iad.exampleuniqueID" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json new file mode 100644 index 00000000000..5f63a1e8122 --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "cb72ae80-1b5a-407e-9f5b-86ddd64df644", + "queryName": "OCI Storage Resources Without CMK", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Storage resources (Object Storage, Block Volumes, Boot Volumes, File Storage) are using default Oracle-managed encryption keys. To satisfy strict compliance requirements, they should be encrypted with a Customer Managed Key (CMK) by defining the 'kms_key_id' attribute.", + "descriptionUrl": "https://docs.oracle.com/en-us/iaas/Content/KeyManagement/Concepts/keyoverview.htm", + "platform": "Terraform", + "descriptionID": "cb72ae80", + "cloudProvider": "oci", + "cwe": "CWE-312", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/query.rego b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/query.rego new file mode 100644 index 00000000000..fcfae666d27 --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/query.rego @@ -0,0 +1,44 @@ +package Cx + +targets := { + "oci_objectstorage_bucket", + "oci_core_volume", + "oci_core_boot_volume", + "oci_file_storage_file_system" +} + +# CASO 1: Falta el atributo kms_key_id (Usa claves gestionadas por Oracle) +CxPolicy[result] { + doc := input.document[i] + + resource := doc.resource[resource_type][name] + targets[resource_type] + + object.get(resource, "kms_key_id", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.%s.%s", [resource_type, name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'%s' should have 'kms_key_id' defined with a Vault Key OCID", [name]), + "keyActualValue": "'kms_key_id' is missing (using Oracle-managed keys)", + } +} + +# CASO 2: El atributo existe pero está vacío +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource[resource_type][name] + targets[resource_type] + + resource.kms_key_id + resource.kms_key_id == "" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.%s.%s.kms_key_id", [resource_type, name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'kms_key_id' should not be empty", + "keyActualValue": "'kms_key_id' is empty", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative1.tf b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative1.tf new file mode 100644 index 00000000000..b55fff6f8b0 --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative1.tf @@ -0,0 +1,11 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_objectstorage_bucket" "bucket_with_cmk" { + compartment_id = "ocid1.compartment.oc1..aaaa" + namespace = "my-namespace" + name = "bucket-secure" + + kms_key_id = "ocid1.key.oc1.iad.example" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative2.tf b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative2.tf new file mode 100644 index 00000000000..56f1735388d --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative2.tf @@ -0,0 +1,11 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_file_storage_file_system" "fs_secure" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment.oc1..aaaa" + display_name = "fs-secure" + + kms_key_id = "ocid1.key.oc1.iad.example" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive1.tf b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive1.tf new file mode 100644 index 00000000000..bee43bee98a --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive1.tf @@ -0,0 +1,9 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_objectstorage_bucket" "bucket_without_cmk" { + compartment_id = "ocid1.compartment.oc1..aaaa" + namespace = "my-namespace" + name = "bucket-insecure" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive2.tf b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive2.tf new file mode 100644 index 00000000000..a9c46eafb79 --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive2.tf @@ -0,0 +1,11 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_volume" "volume_empty_cmk" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment.oc1..aaaa" + display_name = "volume-empty" + + kms_key_id = "" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive_expected_result.json new file mode 100644 index 00000000000..a762ba46ea8 --- /dev/null +++ b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "OCI Storage Resources Without CMK", + "severity": "MEDIUM", + "line": 5, + "fileName": "positive1.tf" + }, + { + "queryName": "OCI Storage Resources Without CMK", + "severity": "MEDIUM", + "line": 10, + "fileName": "positive2.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/README.md b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/README.md new file mode 100644 index 00000000000..5143fc1f110 --- /dev/null +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/README.md @@ -0,0 +1,56 @@ +# Regla KICS: VCN Flow Logging Habilitado + +## Descripción General + +Esta regla de KICS para Terraform asegura que todas las subredes de una VCN (Virtual Cloud Network) en OCI tengan el registro de flujos (`Flow Logging`) correctamente configurado y habilitado. + +La monitorización del tráfico de red es crucial para la detección de anomalías y la resolución de incidentes, cumpliendo con las recomendaciones de seguridad CIS. + +## Lógica de la Regla + +La política se divide en cuatro comprobaciones: +1. **Huérfano:** Subredes sin ningún recurso de log que las apunte. +2. **Estado:** Logs de flujo marcados como `is_enabled = false`. +3. **Tipo:** Logs de servicio que no usan el `log_type = "SERVICE"`. +4. **Servicio:** Logs que no especifican `service = "flowlogs"` en su origen. + +## Casos de Fallo Detectados + +### Caso 1: Subred sin Log Asociado +* **Descripción:** Falta la definición del log para la subred. +* **Ubicación:** Recurso `oci_core_subnet`. + +### Caso 2: Log de Flujo Deshabilitado +* **Descripción:** El atributo `is_enabled` está en `false`. +* **Ubicación:** Atributo `is_enabled` en `oci_logging_log`. + +### Caso 3: Log de Flujo con el Tipo Incorrecto +* **Descripción:** `log_type` no es `"SERVICE"`. +* **Ubicación:** Atributo `log_type` en `oci_logging_log`. + +### Caso 4: Log de Flujo con el Servicio Incorrecto +* **Descripción:** El servicio configurado no es `"flowlogs"`. +* **Ubicación:** Atributo `service` dentro del bloque `source`. + +## Recursos Involucrados + +* `oci_core_subnet` +* `oci_logging_log` + +## Solución + +```terraform +resource "oci_logging_log" "vcn_flow_log" { + display_name = "subnet_flow_log" + log_group_id = oci_logging_log_group.example_log_group.id + log_type = "SERVICE" + is_enabled = true + + configuration { + source { + resource = oci_core_subnet.example_subnet.id + service = "flowlogs" + category = "all" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json new file mode 100644 index 00000000000..16a25033e7a --- /dev/null +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "30d3bb83-f6aa-4302-a647-c404f12f8b8a", + "queryName": "VCN Subnet Without Flow Log", + "severity": "HIGH", + "category": "Observability", + "descriptionText": "VCN Subnet should have flow logging enabled to monitor traffic, as per CIS v3.0.0 recommendation 4.13.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_subnet", + "platform": "Terraform", + "descriptionID": "30d3bb83", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": 6.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/query.rego b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/query.rego new file mode 100644 index 00000000000..cdce921cd2f --- /dev/null +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/query.rego @@ -0,0 +1,73 @@ +package Cx + +# REGLA 1: No existe ningún log asociado a la subred (Missing) +CxPolicy[result] { + doc := input.document[i] + _ := doc.resource.oci_core_subnet[subnet_name] + + associated_logs := [l | + l := input.document[_].resource.oci_logging_log[_] + contains(l.configuration.source.resource, subnet_name) + ] + count(associated_logs) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_core_subnet.%s", [subnet_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "Subnet to have an associated VCN flow log", + "keyActualValue": "Subnet does not have an associated VCN flow log", + } +} + +# REGLA 2: Un log de flujo está deshabilitado +CxPolicy[result] { + doc := input.document[i] + log := doc.resource.oci_logging_log[log_name] + + log.log_type == "SERVICE" + object.get(log.configuration.source, "service", "") == "flowlogs" + log.is_enabled == false + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_logging_log.%s.is_enabled", [log_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be 'true'", + "keyActualValue": "'is_enabled' is 'false'", + } +} + +# REGLA 3: Un log de flujo tiene el tipo incorrecto +CxPolicy[result] { + doc := input.document[i] + log := doc.resource.oci_logging_log[log_name] + + object.get(log.configuration.source, "service", "") == "flowlogs" + log.log_type != "SERVICE" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_logging_log.%s.log_type", [log_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'log_type' should be 'SERVICE'", + "keyActualValue": sprintf("'log_type' is '%s'", [log.log_type]), + } +} + +# REGLA 4: Un log de flujo tiene el servicio incorrecto +CxPolicy[result] { + doc := input.document[i] + log := doc.resource.oci_logging_log[log_name] + + log.log_type == "SERVICE" + object.get(log.configuration.source, "service", "") != "flowlogs" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_logging_log.%s.configuration.source.service", [log_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'service' should be 'flowlogs'", + "keyActualValue": sprintf("'service' is '%s'", [object.get(log.configuration.source, "service", "undefined")]), + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/negative1.tf b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/negative1.tf new file mode 100644 index 00000000000..3ca9e0f1246 --- /dev/null +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/negative1.tf @@ -0,0 +1,21 @@ +resource "oci_core_subnet" "secure_subnet" { + cidr_block = "10.0.1.0/24" + compartment_id = "ocid1.compartment.oc1..aaaa" + vcn_id = "ocid1.vcn.oc1..bbbb" + display_name = "secure_subnet" +} + +resource "oci_logging_log" "secure_flow_log" { + display_name = "secure_log" + log_group_id = "ocid1.loggroup.oc1..cccc" + log_type = "SERVICE" + is_enabled = true + + configuration { + source { + resource = oci_core_subnet.secure_subnet.id + service = "flowlogs" + category = "all" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive1.tf b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive1.tf new file mode 100644 index 00000000000..aabb4d49dab --- /dev/null +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive1.tf @@ -0,0 +1,6 @@ +resource "oci_core_subnet" "subnet_without_log" { + cidr_block = "10.0.1.0/24" + compartment_id = "ocid1.compartment.oc1..aaaa" + vcn_id = "ocid1.vcn.oc1..bbbb" + display_name = "orphan_subnet" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive2.tf b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive2.tf new file mode 100644 index 00000000000..25b5435ae62 --- /dev/null +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive2.tf @@ -0,0 +1,15 @@ +resource "oci_logging_log" "disabled_flow_log" { + display_name = "disabled_log" + log_group_id = "ocid1.loggroup.oc1..cccc" + log_type = "SERVICE" + + # FALLO: Deshabilitado + is_enabled = false + + configuration { + source { + resource = "ocid1.subnet.oc1..aaaa" + service = "flowlogs" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive3.tf b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive3.tf new file mode 100644 index 00000000000..790e68430cb --- /dev/null +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive3.tf @@ -0,0 +1,15 @@ +resource "oci_logging_log" "wrong_type_log" { + display_name = "wrong_type" + log_group_id = "ocid1.loggroup.oc1..cccc" + + # FALLO: Debería ser SERVICE + log_type = "CUSTOM" + is_enabled = true + + configuration { + source { + resource = "ocid1.subnet.oc1..aaaa" + service = "flowlogs" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive4.tf b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive4.tf new file mode 100644 index 00000000000..b20dee2c0fa --- /dev/null +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive4.tf @@ -0,0 +1,14 @@ +resource "oci_logging_log" "wrong_service_log" { + display_name = "wrong_service" + log_group_id = "ocid1.loggroup.oc1..cccc" + log_type = "SERVICE" + is_enabled = true + + configuration { + source { + resource = "ocid1.subnet.oc1..aaaa" + # FALLO: Debería ser flowlogs + service = "wronglogs" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive_expected_result.json new file mode 100644 index 00000000000..487c19e8a97 --- /dev/null +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive_expected_result.json @@ -0,0 +1,26 @@ +[ + { + "queryName": "VCN Subnet Without Flow Log", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "VCN Subnet Without Flow Log", + "severity": "HIGH", + "line": 7, + "fileName": "positive2.tf" + }, + { + "queryName": "VCN Subnet Without Flow Log", + "severity": "HIGH", + "line": 6, + "fileName": "positive3.tf" + }, + { + "queryName": "VCN Subnet Without Flow Log", + "severity": "HIGH", + "line": 11, + "fileName": "positive4.tf" + } +] \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/README.md new file mode 100644 index 00000000000..5b1d6fa4753 --- /dev/null +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/README.md @@ -0,0 +1,54 @@ +# Regla KICS: Notificación para Cambios en VCN en OCI + +## Descripción General + +Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio (creación, actualización o eliminación) en las Redes Virtuales en la Nube (VCN) de la cuenta de OCI. + +Las VCN son el componente fundamental de la red en OCI. Cambios no autorizados pueden tener un impacto severo en la conectividad y la seguridad de los servicios. + +## Lógica de la Regla + +La política verifica la configuración de los recursos `oci_events_rule` buscando los tres tipos de eventos fundamentales: +* `com.oraclecloud.virtualnetwork.createvcn` +* `com.oraclecloud.virtualnetwork.updatevcn` +* `com.oraclecloud.virtualnetwork.deletevcn` + +## Casos de Fallo Detectados + +### Caso 1: Regla Ausente (Missing) +* **Descripción:** No existe ninguna regla en la configuración que monitorice cambios en VCNs. +* **Ubicación:** Bloque `provider "oci"`. + +### Caso 2: Regla Incompleta (Incomplete) +* **Descripción:** Existe una regla pero no incluye los tres eventos requeridos (create, update, delete). +* **Ubicación:** Atributo `condition`. + +### Caso 3: Regla Deshabilitada (Disabled) +* **Descripción:** Existe una regla relevante pero el atributo `is_enabled` es `false`. +* **Ubicación:** Atributo `is_enabled`. + +## Solución + +Asegúrate de incluir una regla habilitada con los eventos correspondientes: + +```terraform +resource "oci_events_rule" "vcn_change_rule" { + display_name = "audit-rule-for-vcn-changes" + compartment_id = var.tenancy_ocid + is_enabled = true + + condition = jsonencode({ + eventType = [ + "com.oraclecloud.virtualnetwork.createvcn", + "com.oraclecloud.virtualnetwork.updatevcn", + "com.oraclecloud.virtualnetwork.deletevcn" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = oci_ons_notification_topic.security_alerts_topic.id + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json new file mode 100644 index 00000000000..361d6d05535 --- /dev/null +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json @@ -0,0 +1,13 @@ +{ + "id": "419bb431-bf37-4e5d-bda6-af3750e808e4", + "queryName": "Event Rule for VCN Changes is Missing", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Virtual Cloud Networks (VCNs). Auditing the creation, modification, and deletion of VCNs is important for detecting unauthorized network changes that could impact security posture.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "419bb431", + "cloudProvider": "oci", + "cwe": "CWE-778", + "riskScore": 3.0 +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego new file mode 100644 index 00000000000..f2223e8e8f1 --- /dev/null +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego @@ -0,0 +1,75 @@ +package Cx + +expected_event_types := [ + "com.oraclecloud.virtualnetwork.createvcn", + "com.oraclecloud.virtualnetwork.updatevcn", + "com.oraclecloud.virtualnetwork.deletevcn" +] + +# REGLA 1: Missing (Global) +# No existe ninguna regla en el proyecto que monitoree cambios en VCNs. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_vcn_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_vcn_rule) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for VCN changes should exist", + "keyActualValue": "No 'oci_events_rule' found for VCN changes", + } +} + +# REGLA 2: Incomplete (Local) +# La regla existe pero le faltan eventos (ej: tiene create pero falta delete). +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 3 VCN events (create, update, delete)", + "keyActualValue": sprintf("The rule is missing %d VCN event(s)", [missing_count]), + } +} + +# REGLA 3: Disabled (Local) +# La regla es relevante para VCN pero está apagada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) > 0 + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/negative1.tf b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/negative1.tf new file mode 100644 index 00000000000..a1a9b5dbc92 --- /dev/null +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/negative1.tf @@ -0,0 +1,24 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "compliant_vcn_rule" { + display_name = "CompliantVCNRule" + compartment_id = "ocid1.tenancy.oc1..aaaa" + is_enabled = true + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createvcn", + "com.oraclecloud.virtualnetwork.updatevcn", + "com.oraclecloud.virtualnetwork.deletevcn" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic.oc1..aaaa" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive1.tf b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive1.tf new file mode 100644 index 00000000000..b6bc413c48c --- /dev/null +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive1.tf @@ -0,0 +1,9 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_vcn" "test_vcn" { + compartment_id = "ocid1.compartment.oc1..aaaa" + cidr_block = "10.0.0.0/16" + display_name = "vulnerable_vcn" +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive2.tf new file mode 100644 index 00000000000..cd99b64e5b6 --- /dev/null +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive2.tf @@ -0,0 +1,23 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "incomplete_vcn_rule" { + display_name = "IncompleteVCNRule" + compartment_id = "ocid1.tenancy.oc1..aaaa" + is_enabled = true + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createvcn", + "com.oraclecloud.virtualnetwork.updatevcn" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic.oc1..aaaa" + } + } +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive3.tf b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive3.tf new file mode 100644 index 00000000000..52e7ca34bc9 --- /dev/null +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive3.tf @@ -0,0 +1,25 @@ +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "disabled_vcn_rule" { + display_name = "DisabledVCNRule" + compartment_id = "ocid1.tenancy.oc1..aaaa" + + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createvcn", + "com.oraclecloud.virtualnetwork.updatevcn", + "com.oraclecloud.virtualnetwork.deletevcn" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic.oc1..aaaa" + } + } + + is_enabled = false +} \ No newline at end of file diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive_expected_result.json new file mode 100644 index 00000000000..7789396e1ca --- /dev/null +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive_expected_result.json @@ -0,0 +1,20 @@ +[ + { + "queryName": "Event Rule for VCN Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Event Rule for VCN Changes is Missing", + "severity": "MEDIUM", + "line": 10, + "fileName": "positive2.tf" + }, + { + "queryName": "Event Rule for VCN Changes is Missing", + "severity": "MEDIUM", + "line": 24, + "fileName": "positive3.tf" + } +] \ No newline at end of file From d3d868424ae70006557789b47a295385687906d5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Mon, 23 Mar 2026 19:17:52 +0000 Subject: [PATCH 002/900] coorected gcp_sql_postgresql_log_statement_improperly_set query --- .../query.rego | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego index a8fc36e8108..8cef3c00b9d 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego @@ -1,5 +1,7 @@ package Cx +import data.generic.terraform as tf_lib + ensure_array(x) = x { is_array(x) } ensure_array(x) = [x] { is_object(x) } @@ -20,7 +22,9 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": sprintf("resource.google_sql_database_instance.%s.settings.database_flags", [name]), + "resourceType": "google_sql_database_instance", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_sql_database_instance[%s].settings.database_flags", [name]), "issueType": "MissingAttribute", "keyExpectedValue": "'database_flags' should include 'log_statement' set to 'ddl', 'mod', or 'all'", "keyActualValue": "'log_statement' flag is missing (defaults to 'none')", @@ -41,7 +45,9 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": sprintf("resource.google_sql_database_instance.%s.settings.database_flags", [name]), + "resourceType": "google_sql_database_instance", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_sql_database_instance[%s].settings.database_flags", [name]), "issueType": "IncorrectValue", "keyExpectedValue": "'log_statement' should be set to 'ddl', 'mod', or 'all'", "keyActualValue": "'log_statement' is set to 'none'", From d133b84a7575d16db9feb70a970b9c25be9c9f92 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Mon, 23 Mar 2026 19:48:24 +0000 Subject: [PATCH 003/900] query gcp_sql_postgresql_log_statement_improperly_set correction --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json index 46a857f7d7b..694b953ce2a 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "ede2d9e4", "cloudProvider": "gcp", "cwe": "CWE-778", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file From df768b9144d65f3ce89c9c7ebb95ffff1316e32c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Mon, 23 Mar 2026 20:31:26 +0000 Subject: [PATCH 004/900] fix issues in the query tests for the new queries --- .../metadata.json | 2 +- .../query.rego | 94 +++++----- .../metadata.json | 2 +- .../query.rego | 82 ++++----- .../metadata.json | 2 +- .../query.rego | 54 +++--- .../metadata.json | 2 +- .../query.rego | 72 ++++---- .../metadata.json | 2 +- .../query.rego | 38 +++-- .../azure_bastion_host_missing/metadata.json | 2 +- .../azure_bastion_host_missing/query.rego | 44 ++--- .../metadata.json | 2 +- .../query.rego | 34 ++-- .../test/negative1.tf | 7 + .../metadata.json | 2 +- .../query.rego | 40 +++-- .../metadata.json | 2 +- .../query.rego | 82 ++++----- .../test/positive_expected_result.json | 4 +- .../metadata.json | 2 +- .../query.rego | 70 ++++---- .../metadata.json | 2 +- .../query.rego | 38 +++-- .../metadata.json | 2 +- .../query.rego | 38 +++-- .../metadata.json | 2 +- .../query.rego | 42 ++--- .../test/negative1.tf | 7 + .../metadata.json | 2 +- .../query.rego | 42 ++--- .../test/negative1.tf | 7 + .../metadata.json | 2 +- .../query.rego | 76 +++++---- .../metadata.json | 2 +- .../query.rego | 112 ++++++------ .../metadata.json | 2 +- .../query.rego | 74 ++++---- .../metadata.json | 2 +- .../query.rego | 38 +++-- .../metadata.json | 2 +- .../query.rego | 72 ++++---- .../metadata.json | 2 +- .../query.rego | 74 ++++---- .../metadata.json | 2 +- .../query.rego | 68 ++++---- .../metadata.json | 2 +- .../query.rego | 46 ++--- .../metadata.json | 2 +- .../query.rego | 72 ++++---- .../metadata.json | 2 +- .../query.rego | 122 ++++++------- .../metadata.json | 2 +- .../query.rego | 110 ++++++------ .../metadata.json | 2 +- .../query.rego | 160 +++++++++--------- .../metadata.json | 2 +- .../query.rego | 72 ++++---- .../metadata.json | 2 +- .../query.rego | 74 ++++---- .../metadata.json | 2 +- .../query.rego | 158 +++++++++-------- .../metadata.json | 2 +- .../query.rego | 160 +++++++++--------- .../metadata.json | 2 +- .../gcp_access_approval_disabled/query.rego | 82 ++++----- .../metadata.json | 2 +- .../query.rego | 74 ++++---- .../metadata.json | 2 +- .../query.rego | 72 ++++---- .../metadata.json | 2 +- .../query.rego | 90 +++++----- .../metadata.json | 2 +- .../query.rego | 110 ++++++------ .../metadata.json | 2 +- .../query.rego | 72 ++++---- .../metadata.json | 2 +- .../query.rego | 110 ++++++------ .../gcp_gke_manual_iam_check/metadata.json | 2 +- .../gcp/gcp_gke_manual_iam_check/query.rego | 72 ++++---- .../metadata.json | 2 +- .../query.rego | 140 ++++++++------- .../gcp_gke_sandbox_disabled/metadata.json | 2 +- .../gcp/gcp_gke_sandbox_disabled/query.rego | 140 ++++++++------- .../metadata.json | 2 +- .../query.rego | 112 ++++++------ .../metadata.json | 2 +- .../query.rego | 72 ++++---- .../metadata.json | 2 +- .../query.rego | 72 ++++---- .../metadata.json | 2 +- .../query.rego | 72 ++++---- .../metadata.json | 2 +- .../query.rego | 110 ++++++------ .../metadata.json | 2 +- .../query.rego | 54 +++--- 96 files changed, 2060 insertions(+), 1769 deletions(-) create mode 100644 assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/negative1.tf create mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/negative1.tf diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json index 72ff8d8cb65..afe786dd933 100644 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "721c26ff", "cloudProvider": "azure", "cwe": "CWE-778", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego index 52d2cefd933..f20fb3ab448 100644 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego @@ -1,44 +1,50 @@ -package Cx - -targets := { - "azurerm_linux_web_app", - "azurerm_windows_web_app", - "azurerm_linux_function_app", - "azurerm_windows_function_app" -} - -# REGLA 1: El bloque 'app_settings' no existe en absoluto. -CxPolicy[result] { - doc := input.document[i] - resource_type := targets[t] - app := doc.resource[resource_type][name] - - not app.app_settings - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.%s.%s", [resource_type, name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'%s.%s' should have 'app_settings' defined", [resource_type, name]), - "keyActualValue": sprintf("'%s.%s' is missing 'app_settings'", [resource_type, name]), - } -} - -# REGLA 2: El bloque 'app_settings' existe pero no tiene ninguna clave de App Insights. -CxPolicy[result] { - doc := input.document[i] - resource_type := targets[t] - app := doc.resource[resource_type][name] - - app.app_settings - not app.app_settings["APPLICATIONINSIGHTS_CONNECTION_STRING"] - not app.app_settings["APPINSIGHTS_INSTRUMENTATIONKEY"] - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.%s.%s.app_settings", [resource_type, name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'app_settings' should contain 'APPLICATIONINSIGHTS_CONNECTION_STRING'", - "keyActualValue": "'app_settings' does not contain Application Insights configuration", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +targets := { + "azurerm_linux_web_app", + "azurerm_windows_web_app", + "azurerm_linux_function_app", + "azurerm_windows_function_app" +} + +# REGLA 1: El bloque 'app_settings' no existe en absoluto. +CxPolicy[result] { + doc := input.document[i] + resource_type := targets[t] + app := doc.resource[resource_type][name] + + not app.app_settings + + result := { + "documentId": doc.id, + "resourceType": resource_type, + "resourceName": tf_lib.get_resource_name(app, name), + "searchKey": sprintf("%s[%s]", [resource_type, name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'%s.%s' should have 'app_settings' defined", [resource_type, name]), + "keyActualValue": sprintf("'%s.%s' is missing 'app_settings'", [resource_type, name]), + } +} + +# REGLA 2: El bloque 'app_settings' existe pero no tiene ninguna clave de App Insights. +CxPolicy[result] { + doc := input.document[i] + resource_type := targets[t] + app := doc.resource[resource_type][name] + + app.app_settings + not app.app_settings["APPLICATIONINSIGHTS_CONNECTION_STRING"] + not app.app_settings["APPINSIGHTS_INSTRUMENTATIONKEY"] + + result := { + "documentId": doc.id, + "resourceType": resource_type, + "resourceName": tf_lib.get_resource_name(app, name), + "searchKey": sprintf("%s[%s].app_settings", [resource_type, name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'app_settings' should contain 'APPLICATIONINSIGHTS_CONNECTION_STRING'", + "keyActualValue": "'app_settings' does not contain Application Insights configuration", + } +} diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json index b30be71a396..95eaf2da695 100644 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "72eb3dd8", "cloudProvider": "azure", "cwe": "CWE-778", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego index 8ed6d368b34..7b56ce92f11 100644 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego @@ -1,38 +1,44 @@ -package Cx - -targets := {"azurerm_linux_web_app", "azurerm_windows_web_app"} - -# REGLA 1: El bloque 'logs' no existe en el App Service. -CxPolicy[result] { - doc := input.document[i] - resource_type := targets[t] - app := doc.resource[resource_type][name] - - not app.logs - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.%s.%s", [resource_type, name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'%s.%s' should have a 'logs' block defined", [resource_type, name]), - "keyActualValue": sprintf("'%s.%s' is missing the 'logs' block", [resource_type, name]), - } -} - -# REGLA 2: El bloque 'logs' existe pero no tiene 'http_logs' configurado. -CxPolicy[result] { - doc := input.document[i] - resource_type := targets[t] - app := doc.resource[resource_type][name] - - app.logs - not app.logs.http_logs - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.%s.%s.logs", [resource_type, name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'%s.%s.logs' should have 'http_logs' configured", [resource_type, name]), - "keyActualValue": sprintf("'%s.%s.logs' is missing 'http_logs'", [resource_type, name]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +targets := {"azurerm_linux_web_app", "azurerm_windows_web_app"} + +# REGLA 1: El bloque 'logs' no existe en el App Service. +CxPolicy[result] { + doc := input.document[i] + resource_type := targets[t] + app := doc.resource[resource_type][name] + + not app.logs + + result := { + "documentId": doc.id, + "resourceType": resource_type, + "resourceName": tf_lib.get_resource_name(app, name), + "searchKey": sprintf("%s[%s]", [resource_type, name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'%s.%s' should have a 'logs' block defined", [resource_type, name]), + "keyActualValue": sprintf("'%s.%s' is missing the 'logs' block", [resource_type, name]), + } +} + +# REGLA 2: El bloque 'logs' existe pero no tiene 'http_logs' configurado. +CxPolicy[result] { + doc := input.document[i] + resource_type := targets[t] + app := doc.resource[resource_type][name] + + app.logs + not app.logs.http_logs + + result := { + "documentId": doc.id, + "resourceType": resource_type, + "resourceName": tf_lib.get_resource_name(app, name), + "searchKey": sprintf("%s[%s].logs", [resource_type, name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'%s.%s.logs' should have 'http_logs' configured", [resource_type, name]), + "keyActualValue": sprintf("'%s.%s.logs' is missing 'http_logs'", [resource_type, name]), + } +} diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json index 4b63512897a..de557efe53d 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "bf4474a7", "cloudProvider": "azure", "cwe": "CWE-326", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego index 114fb74bd78..1e78a4e383c 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego @@ -1,25 +1,29 @@ -package Cx - -has_cmk_configured(doc, vault_id) { - cmk := doc.resource.azurerm_data_protection_backup_vault_customer_managed_key[_] - cmk.data_protection_backup_vault_id == vault_id - cmk.key_vault_key_id -} - -# REGLA 1: El Backup Vault no tiene cifrado CMK configurado a través del recurso de asociación. -CxPolicy[result] { - doc := input.document[i] - vault := doc.resource.azurerm_data_protection_backup_vault[name] - - vault_id := sprintf("${azurerm_data_protection_backup_vault.%s.id}", [name]) - - not has_cmk_configured(doc, vault_id) - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_data_protection_backup_vault.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should be associated with an 'azurerm_data_protection_backup_vault_customer_managed_key' resource", [name]), - "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is using Platform-Managed Keys (default)", [name]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +has_cmk_configured(doc, vault_id) { + cmk := doc.resource.azurerm_data_protection_backup_vault_customer_managed_key[_] + cmk.data_protection_backup_vault_id == vault_id + cmk.key_vault_key_id +} + +# REGLA 1: El Backup Vault no tiene cifrado CMK configurado a través del recurso de asociación. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_data_protection_backup_vault[name] + + vault_id := sprintf("${azurerm_data_protection_backup_vault.%s.id}", [name]) + + not has_cmk_configured(doc, vault_id) + + result := { + "documentId": doc.id, + "resourceType": "azurerm_data_protection_backup_vault", + "resourceName": tf_lib.get_resource_name(vault, name), + "searchKey": sprintf("azurerm_data_protection_backup_vault[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should be associated with an 'azurerm_data_protection_backup_vault_customer_managed_key' resource", [name]), + "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is using Platform-Managed Keys (default)", [name]), + } +} diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json index 5bb3f8ea098..2dc65346e16 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "0117fb32", "cloudProvider": "azure", "cwe": "CWE-668", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego index 899dc447728..c119b997648 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego @@ -1,33 +1,39 @@ -package Cx - -# REGLA 1: Configuración Ausente. -CxPolicy[result] { - doc := input.document[i] - vault := doc.resource.azurerm_data_protection_backup_vault[name] - - object.get(vault, "cross_region_restore_enabled", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_data_protection_backup_vault.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should have 'cross_region_restore_enabled' set to true", [name]), - "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is missing 'cross_region_restore_enabled'", [name]), - } -} - -# REGLA 2: Configuración Incorrecta (Deshabilitado explícitamente). -CxPolicy[result] { - doc := input.document[i] - vault := doc.resource.azurerm_data_protection_backup_vault[name] - - vault.cross_region_restore_enabled == false - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_data_protection_backup_vault.%s.cross_region_restore_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'cross_region_restore_enabled' should be set to true", - "keyActualValue": "'cross_region_restore_enabled' is set to false", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Configuración Ausente. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_data_protection_backup_vault[name] + + object.get(vault, "cross_region_restore_enabled", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "resourceType": "azurerm_data_protection_backup_vault", + "resourceName": tf_lib.get_resource_name(vault, name), + "searchKey": sprintf("azurerm_data_protection_backup_vault[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should have 'cross_region_restore_enabled' set to true", [name]), + "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is missing 'cross_region_restore_enabled'", [name]), + } +} + +# REGLA 2: Configuración Incorrecta (Deshabilitado explícitamente). +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_data_protection_backup_vault[name] + + vault.cross_region_restore_enabled == false + + result := { + "documentId": doc.id, + "resourceType": "azurerm_data_protection_backup_vault", + "resourceName": tf_lib.get_resource_name(vault, name), + "searchKey": sprintf("azurerm_data_protection_backup_vault[%s].cross_region_restore_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'cross_region_restore_enabled' should be set to true", + "keyActualValue": "'cross_region_restore_enabled' is set to false", + } +} diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json index e766039db6a..72af6f2ffac 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "f7bf03d5", "cloudProvider": "azure", "cwe": "CWE-312", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego index 42de971f8c9..f76ea1d04fe 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego @@ -1,17 +1,21 @@ -package Cx - -# REGLA 1: Falta el bloque 'identity', necesario para gestionar cifrado avanzado. -CxPolicy[result] { - doc := input.document[i] - vault := doc.resource.azurerm_data_protection_backup_vault[name] - - not vault.identity - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_data_protection_backup_vault.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should have an 'identity' block to support advanced encryption", [name]), - "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is missing the 'identity' block", [name]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Falta el bloque 'identity', necesario para gestionar cifrado avanzado. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_data_protection_backup_vault[name] + + not vault.identity + + result := { + "documentId": doc.id, + "resourceType": "azurerm_data_protection_backup_vault", + "resourceName": tf_lib.get_resource_name(vault, name), + "searchKey": sprintf("azurerm_data_protection_backup_vault[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should have an 'identity' block to support advanced encryption", [name]), + "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is missing the 'identity' block", [name]), + } +} diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json b/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json index b21e74e168d..ca98958d416 100644 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "a3e941c5", "cloudProvider": "azure", "cwe": "CWE-284", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego b/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego index 0f5dabba3ac..b777996ee5d 100644 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego @@ -1,20 +1,24 @@ -package Cx - -# REGLA 1: Existe una VNet, pero no existe ningún recurso azurerm_bastion_host en el documento. -CxPolicy[result] { - doc := input.document[i] - - vnet := doc.resource.azurerm_virtual_network[name] - - bastions := [b | b := doc.resource.azurerm_bastion_host[_]] - - count(bastions) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_virtual_network.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("An 'azurerm_bastion_host' resource should be defined to protect Virtual Network '%s'", [name]), - "keyActualValue": "No 'azurerm_bastion_host' resource was found in the configuration", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Existe una VNet, pero no existe ningún recurso azurerm_bastion_host en el documento. +CxPolicy[result] { + doc := input.document[i] + + vnet := doc.resource.azurerm_virtual_network[name] + + bastions := [b | b := doc.resource.azurerm_bastion_host[_]] + + count(bastions) == 0 + + result := { + "documentId": doc.id, + "resourceType": "azurerm_virtual_network", + "resourceName": tf_lib.get_resource_name(vnet, name), + "searchKey": sprintf("azurerm_virtual_network[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("An 'azurerm_bastion_host' resource should be defined to protect Virtual Network '%s'", [name]), + "keyActualValue": "No 'azurerm_bastion_host' resource was found in the configuration", + } +} diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json index 9f1fe2d2c5a..637929c90d2 100644 --- a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "b9f8511b", "cloudProvider": "azure", "cwe": "CWE-778", - "riskScore": 0.0 + "riskScore": "0.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego index b0084fd4d98..e7bfbf42b0e 100644 --- a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego +++ b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego @@ -1,15 +1,19 @@ -package Cx - -# REGLA 1: Genera un aviso manual por cada Resource Group encontrado. -CxPolicy[result] { - doc := input.document[i] - rg := doc.resource.azurerm_resource_group[name] - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_resource_group.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("Microsoft Defender EASM should be verified manually for resource group '%s'", [name]), - "keyActualValue": "EASM status cannot be verified statically via Terraform (Manual Verification Required)", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Genera un aviso manual por cada Resource Group encontrado. +CxPolicy[result] { + doc := input.document[i] + rg := doc.resource.azurerm_resource_group[name] + + result := { + "documentId": doc.id, + "resourceType": "azurerm_resource_group", + "resourceName": tf_lib.get_resource_name(rg, name), + "searchKey": sprintf("azurerm_resource_group[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("Microsoft Defender EASM should be verified manually for resource group '%s'", [name]), + "keyActualValue": "EASM status cannot be verified statically via Terraform (Manual Verification Required)", + } +} diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/negative1.tf b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/negative1.tf new file mode 100644 index 00000000000..c8ce844cce0 --- /dev/null +++ b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/negative1.tf @@ -0,0 +1,7 @@ +resource "azurerm_storage_account" "no_rg_here" { + name = "storageaccountneg1" + resource_group_name = "rg-existing" + location = "East US" + account_tier = "Standard" + account_replication_type = "LRS" +} diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json index 9bf0857c145..e5b0c20030c 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-284", "descriptionID": "660863a5", - "riskScore": 9.0 + "riskScore": "9.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego index ab3e86102fe..5cda347b958 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego @@ -1,18 +1,22 @@ -package Cx - -# REGLA 1: El bloque 'network_rule' no está definido. -# En azurerm_elastic_san_volume_group, la ausencia del bloque permite el acceso público. -CxPolicy[result] { - doc := input.document[i] - vg := doc.resource.azurerm_elastic_san_volume_group[name] - - not vg.network_rule - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_elastic_san_volume_group.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_elastic_san_volume_group.%s' should have a 'network_rule' block to restrict public access", [name]), - "keyActualValue": sprintf("'azurerm_elastic_san_volume_group.%s' is missing the 'network_rule' block", [name]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: El bloque 'network_rule' no está definido. +# En azurerm_elastic_san_volume_group, la ausencia del bloque permite el acceso público. +CxPolicy[result] { + doc := input.document[i] + vg := doc.resource.azurerm_elastic_san_volume_group[name] + + not vg.network_rule + + result := { + "documentId": doc.id, + "resourceType": "azurerm_elastic_san_volume_group", + "resourceName": tf_lib.get_resource_name(vg, name), + "searchKey": sprintf("azurerm_elastic_san_volume_group[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_elastic_san_volume_group.%s' should have a 'network_rule' block to restrict public access", [name]), + "keyActualValue": sprintf("'azurerm_elastic_san_volume_group.%s' is missing the 'network_rule' block", [name]), + } +} diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json index 0da8c3ce89b..b0395ce911a 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-326", "descriptionID": "3b101ad5", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego index 9cee7397bb0..e1d3f3a9fa8 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego @@ -1,38 +1,44 @@ -package Cx - -# REGLA 1: El tipo de cifrado no es CMK o no está definido. -CxPolicy[result] { - doc := input.document[i] - vg := doc.resource.azurerm_elastic_san_volume_group[name] - - object.get(vg, "encryption_type", "undefined") != "EncryptionAtRestWithCustomerManagedKey" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_elastic_san_volume_group.%s", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'encryption_type' should be set to 'EncryptionAtRestWithCustomerManagedKey'", - "keyActualValue": sprintf("'encryption_type' is set to '%v'", [object.get(vg, "encryption_type", "PlatformKey (Default)")]), - } -} - -# REGLA 2: Si el tipo es CMK, debe existir tanto el bloque 'encryption' como el bloque 'identity'. -CxPolicy[result] { - doc := input.document[i] - vg := doc.resource.azurerm_elastic_san_volume_group[name] - vg.encryption_type == "EncryptionAtRestWithCustomerManagedKey" - - required_blocks := {"encryption", "identity"} - existing_blocks := {b | vg[b]} - missing := required_blocks - existing_blocks - - count(missing) > 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_elastic_san_volume_group.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_elastic_san_volume_group.%s' should have both 'encryption' and 'identity' blocks for CMK", [name]), - "keyActualValue": sprintf("'azurerm_elastic_san_volume_group.%s' is missing the following block(s): %s", [name, concat(", ", missing)]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: El tipo de cifrado no es CMK o no está definido. +CxPolicy[result] { + doc := input.document[i] + vg := doc.resource.azurerm_elastic_san_volume_group[name] + + object.get(vg, "encryption_type", "undefined") != "EncryptionAtRestWithCustomerManagedKey" + + result := { + "documentId": doc.id, + "resourceType": "azurerm_elastic_san_volume_group", + "resourceName": tf_lib.get_resource_name(vg, name), + "searchKey": sprintf("azurerm_elastic_san_volume_group[%s]", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'encryption_type' should be set to 'EncryptionAtRestWithCustomerManagedKey'", + "keyActualValue": sprintf("'encryption_type' is set to '%v'", [object.get(vg, "encryption_type", "PlatformKey (Default)")]), + } +} + +# REGLA 2: Si el tipo es CMK, debe existir tanto el bloque 'encryption' como el bloque 'identity'. +CxPolicy[result] { + doc := input.document[i] + vg := doc.resource.azurerm_elastic_san_volume_group[name] + vg.encryption_type == "EncryptionAtRestWithCustomerManagedKey" + + required_blocks := {"encryption", "identity"} + existing_blocks := {b | vg[b]} + missing := required_blocks - existing_blocks + + count(missing) > 0 + + result := { + "documentId": doc.id, + "resourceType": "azurerm_elastic_san_volume_group", + "resourceName": tf_lib.get_resource_name(vg, name), + "searchKey": sprintf("azurerm_elastic_san_volume_group[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_elastic_san_volume_group.%s' should have both 'encryption' and 'identity' blocks for CMK", [name]), + "keyActualValue": sprintf("'azurerm_elastic_san_volume_group.%s' is missing the following block(s): %s", [name, concat(", ", missing)]), + } +} diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json index c0f988b83b3..32f203345b4 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json @@ -3,12 +3,12 @@ "queryName": "Elastic SAN Volume Group CMK Encryption Disabled", "severity": "MEDIUM", "line": 1, - "fileName": "positive.tf" + "fileName": "positive1.tf" }, { "queryName": "Elastic SAN Volume Group CMK Encryption Disabled", "severity": "MEDIUM", "line": 1, - "fileName": "positive.tf" + "fileName": "positive2.tf" } ] \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json index 4c7522e2bb0..9ab57e0d2f8 100644 --- a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-693", "descriptionID": "13be738b", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego index 13c444b6108..e6d34c49b56 100644 --- a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego @@ -1,33 +1,37 @@ -package Cx - -# REGLA 1: IoT Hub sin solución de seguridad (azurerm_iot_security_solution) asociada. -CxPolicy[result] { - doc := input.document[i] - iot_hub := doc.resource.azurerm_iothub[hub_name] - - hub_ref := sprintf("azurerm_iothub.%s.id", [hub_name]) - - solutions := [sol | - sol := doc.resource.azurerm_iot_security_solution[_] - current_hub_id := sol.iothub_ids[_] - check_hub_id(current_hub_id, hub_ref) - ] - - count(solutions) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_iothub.%s", [hub_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_iothub.%s' should be included in 'iothub_ids' of an 'azurerm_iot_security_solution'", [hub_name]), - "keyActualValue": sprintf("'azurerm_iothub.%s' is not associated with any 'azurerm_iot_security_solution'", [hub_name]), - } -} - -check_hub_id(current, target) { - current == target -} - -check_hub_id(current, target) { - current == sprintf("${%s}", [target]) -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: IoT Hub sin solución de seguridad (azurerm_iot_security_solution) asociada. +CxPolicy[result] { + doc := input.document[i] + iot_hub := doc.resource.azurerm_iothub[hub_name] + + hub_ref := sprintf("azurerm_iothub.%s.id", [hub_name]) + + solutions := [sol | + sol := doc.resource.azurerm_iot_security_solution[_] + current_hub_id := sol.iothub_ids[_] + check_hub_id(current_hub_id, hub_ref) + ] + + count(solutions) == 0 + + result := { + "documentId": doc.id, + "resourceType": "azurerm_iothub", + "resourceName": tf_lib.get_resource_name(iot_hub, hub_name), + "searchKey": sprintf("azurerm_iothub[%s]", [hub_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_iothub.%s' should be included in 'iothub_ids' of an 'azurerm_iot_security_solution'", [hub_name]), + "keyActualValue": sprintf("'azurerm_iothub.%s' is not associated with any 'azurerm_iot_security_solution'", [hub_name]), + } +} + +check_hub_id(current, target) { + current == target +} + +check_hub_id(current, target) { + current == sprintf("${%s}", [target]) +} diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json index 6498e1bff29..cfe4588462c 100644 --- a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-320", "descriptionID": "ca1ffce5", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego index 13ca1cc6da7..9ff8c50a62f 100644 --- a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego @@ -1,17 +1,21 @@ -package Cx - -# REGLA 1: La clave del Key Vault no tiene política de rotación configurada. -CxPolicy[result] { - doc := input.document[i] - key := doc.resource.azurerm_key_vault_key[name] - - not key.rotation_policy - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_key_vault_key.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_key_vault_key.%s' should have a 'rotation_policy' block defined", [name]), - "keyActualValue": sprintf("'azurerm_key_vault_key.%s' does not have a 'rotation_policy' block defined", [name]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: La clave del Key Vault no tiene política de rotación configurada. +CxPolicy[result] { + doc := input.document[i] + key := doc.resource.azurerm_key_vault_key[name] + + not key.rotation_policy + + result := { + "documentId": doc.id, + "resourceType": "azurerm_key_vault_key", + "resourceName": tf_lib.get_resource_name(key, name), + "searchKey": sprintf("azurerm_key_vault_key[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_key_vault_key.%s' should have a 'rotation_policy' block defined", [name]), + "keyActualValue": sprintf("'azurerm_key_vault_key.%s' does not have a 'rotation_policy' block defined", [name]), + } +} diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json index 752e13181c2..9b364bf8e86 100644 --- a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-326", "descriptionID": "7fc653e2", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego index d0b0f475678..c757a60bbc2 100644 --- a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego @@ -1,17 +1,21 @@ -package Cx - -# REGLA 1: El bloque 'encryption_key' no está definido. -CxPolicy[result] { - doc := input.document[i] - lustre := doc.resource.azurerm_managed_lustre_file_system[name] - - not lustre.encryption_key - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_managed_lustre_file_system.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_managed_lustre_file_system.%s' should have an 'encryption_key' block defined", [name]), - "keyActualValue": sprintf("'azurerm_managed_lustre_file_system.%s' is missing the 'encryption_key' block", [name]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: El bloque 'encryption_key' no está definido. +CxPolicy[result] { + doc := input.document[i] + lustre := doc.resource.azurerm_managed_lustre_file_system[name] + + not lustre.encryption_key + + result := { + "documentId": doc.id, + "resourceType": "azurerm_managed_lustre_file_system", + "resourceName": tf_lib.get_resource_name(lustre, name), + "searchKey": sprintf("azurerm_managed_lustre_file_system[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_managed_lustre_file_system.%s' should have an 'encryption_key' block defined", [name]), + "keyActualValue": sprintf("'azurerm_managed_lustre_file_system.%s' is missing the 'encryption_key' block", [name]), + } +} diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json index 11e04045ca4..d385f664b47 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-778", "descriptionID": "8d8ac482", - "riskScore": 0.0 + "riskScore": "0.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego index 5c28617c5cf..0023adb1aec 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego @@ -1,19 +1,23 @@ -package Cx - -targets := {"azurerm_mssql_server", "azurerm_mysql_flexible_server"} - -# REGLA MANUAL: Detecta servidores MySQL para solicitar verificación de logs de auditoría. -CxPolicy[result] { - doc := input.document[i] - - resource_type := targets[t] - server := doc.resource[resource_type][name] - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.%s.%s", [resource_type, name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'audit_log_enabled' should be set to 'ON' for '%s.%s' (Manual Verification)", [resource_type, name]), - "keyActualValue": "Logging configuration requires manual verification or check of 'azurerm_mysql_configuration' resources", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +targets := {"azurerm_mssql_server", "azurerm_mysql_flexible_server"} + +# REGLA MANUAL: Detecta servidores MySQL para solicitar verificación de logs de auditoría. +CxPolicy[result] { + doc := input.document[i] + + resource_type := targets[t] + server := doc.resource[resource_type][name] + + result := { + "documentId": doc.id, + "resourceType": resource_type, + "resourceName": tf_lib.get_resource_name(server, name), + "searchKey": sprintf("%s[%s]", [resource_type, name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'audit_log_enabled' should be set to 'ON' for '%s.%s' (Manual Verification)", [resource_type, name]), + "keyActualValue": "Logging configuration requires manual verification or check of 'azurerm_mysql_configuration' resources", + } +} diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/negative1.tf b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/negative1.tf new file mode 100644 index 00000000000..b1137217038 --- /dev/null +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/negative1.tf @@ -0,0 +1,7 @@ +resource "azurerm_storage_account" "no_mysql_here" { + name = "storageaccountneg1" + resource_group_name = "rg-test" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json index d5160af4619..5c03bdb8c92 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-778", "descriptionID": "fe65cd89", - "riskScore": 0.0 + "riskScore": "0.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego index 91355c01e0e..cfc0c13ccf1 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego @@ -1,19 +1,23 @@ -package Cx - -targets := {"azurerm_mssql_server", "azurerm_mysql_flexible_server"} - -# REGLA MANUAL: Detecta servidores MySQL para solicitar verificación del evento CONNECTION. -CxPolicy[result] { - doc := input.document[i] - - resource_type := targets[t] - server := doc.resource[resource_type][name] - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.%s.%s", [resource_type, name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'audit_log_events' should include 'CONNECTION' for '%s.%s' (Manual Verification)", [resource_type, name]), - "keyActualValue": "Audit log event configuration requires manual verification or check of 'azurerm_mysql_configuration'", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +targets := {"azurerm_mssql_server", "azurerm_mysql_flexible_server"} + +# REGLA MANUAL: Detecta servidores MySQL para solicitar verificación del evento CONNECTION. +CxPolicy[result] { + doc := input.document[i] + + resource_type := targets[t] + server := doc.resource[resource_type][name] + + result := { + "documentId": doc.id, + "resourceType": resource_type, + "resourceName": tf_lib.get_resource_name(server, name), + "searchKey": sprintf("%s[%s]", [resource_type, name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'audit_log_events' should include 'CONNECTION' for '%s.%s' (Manual Verification)", [resource_type, name]), + "keyActualValue": "Audit log event configuration requires manual verification or check of 'azurerm_mysql_configuration'", + } +} diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/negative1.tf b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/negative1.tf new file mode 100644 index 00000000000..b1137217038 --- /dev/null +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/negative1.tf @@ -0,0 +1,7 @@ +resource "azurerm_storage_account" "no_mysql_here" { + name = "storageaccountneg1" + resource_group_name = "rg-test" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" +} diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json index e98c7036089..3a9cb5216a0 100644 --- a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-326", "descriptionID": "8bed44b5", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego index aaef399b3a3..6a686cfe748 100644 --- a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego @@ -1,36 +1,40 @@ -package Cx - -has_encryption_resource(doc, account_id) { - enc := doc.resource.azurerm_netapp_account_encryption[_] - check_id(enc.netapp_account_id, account_id) -} - -check_id(current, target) { - current == target -} - -check_id(current, target) { - current == sprintf("${%s}", [target]) -} - -has_inline_encryption(account) { - account.encryption.key_source == "Microsoft.KeyVault" -} - -# REGLA 1: La cuenta NetApp utiliza Platform-Managed Keys (falta configuración CMK). -CxPolicy[result] { - doc := input.document[i] - account := doc.resource.azurerm_netapp_account[name] - account_id := sprintf("azurerm_netapp_account.%s.id", [name]) - - not has_inline_encryption(account) - not has_encryption_resource(doc, account_id) - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_netapp_account.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_netapp_account.%s' should have 'encryption.key_source' set to 'Microsoft.KeyVault' or have an 'azurerm_netapp_account_encryption' resource associated", [name]), - "keyActualValue": sprintf("'azurerm_netapp_account.%s' is using Platform-Managed Keys (default)", [name]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +has_encryption_resource(doc, account_id) { + enc := doc.resource.azurerm_netapp_account_encryption[_] + check_id(enc.netapp_account_id, account_id) +} + +check_id(current, target) { + current == target +} + +check_id(current, target) { + current == sprintf("${%s}", [target]) +} + +has_inline_encryption(account) { + account.encryption.key_source == "Microsoft.KeyVault" +} + +# REGLA 1: La cuenta NetApp utiliza Platform-Managed Keys (falta configuración CMK). +CxPolicy[result] { + doc := input.document[i] + account := doc.resource.azurerm_netapp_account[name] + account_id := sprintf("azurerm_netapp_account.%s.id", [name]) + + not has_inline_encryption(account) + not has_encryption_resource(doc, account_id) + + result := { + "documentId": doc.id, + "resourceType": "azurerm_netapp_account", + "resourceName": tf_lib.get_resource_name(account, name), + "searchKey": sprintf("azurerm_netapp_account[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_netapp_account.%s' should have 'encryption.key_source' set to 'Microsoft.KeyVault' or have an 'azurerm_netapp_account_encryption' resource associated", [name]), + "keyActualValue": sprintf("'azurerm_netapp_account.%s' is using Platform-Managed Keys (default)", [name]), + } +} diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json index a17522eb843..323e9a36184 100644 --- a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-200", "descriptionID": "dda11a20", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego index fc1b7a752a0..e012f8ad5e4 100644 --- a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego @@ -1,54 +1,58 @@ -package Cx - -targets := { - "azurerm_cosmosdb_account", - "azurerm_storage_account", - "azurerm_mssql_server", - "azurerm_key_vault", - "azurerm_container_registry", - "azurerm_servicebus_namespace", - "azurerm_mariadb_server", - "azurerm_postgresql_server", - "azurerm_mysql_server", - "azurerm_redis_cache", - "azurerm_eventhub_namespace", - "azurerm_automation_account", - "azurerm_data_factory", - "azurerm_synapse_workspace", - "azurerm_search_service" -} - -# REGLA MAESTRA: Verifica si los recursos de la lista targets tienen un Private Endpoint vinculado. -CxPolicy[result] { - doc := input.document[i] - - resource_type := targets[t] - resource_instances := doc.resource[resource_type] - resource_instance := resource_instances[name] - - target_id := sprintf("%s.%s.id", [resource_type, name]) - - private_endpoints := [pe | - pe := doc.resource.azurerm_private_endpoint[_] - conn := pe.private_service_connection - check_resource_id(conn.private_connection_resource_id, target_id) - ] - - count(private_endpoints) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.%s.%s", [resource_type, name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'%s.%s' should be linked to an 'azurerm_private_endpoint'", [resource_type, name]), - "keyActualValue": sprintf("'%s.%s' is not linked to any 'azurerm_private_endpoint' in this file", [resource_type, name]), - } -} - -check_resource_id(current, target) { - current == target -} - -check_resource_id(current, target) { - current == sprintf("${%s}", [target]) -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +targets := { + "azurerm_cosmosdb_account", + "azurerm_storage_account", + "azurerm_mssql_server", + "azurerm_key_vault", + "azurerm_container_registry", + "azurerm_servicebus_namespace", + "azurerm_mariadb_server", + "azurerm_postgresql_server", + "azurerm_mysql_server", + "azurerm_redis_cache", + "azurerm_eventhub_namespace", + "azurerm_automation_account", + "azurerm_data_factory", + "azurerm_synapse_workspace", + "azurerm_search_service" +} + +# REGLA MAESTRA: Verifica si los recursos de la lista targets tienen un Private Endpoint vinculado. +CxPolicy[result] { + doc := input.document[i] + + resource_type := targets[t] + resource_instances := doc.resource[resource_type] + resource_instance := resource_instances[name] + + target_id := sprintf("%s.%s.id", [resource_type, name]) + + private_endpoints := [pe | + pe := doc.resource.azurerm_private_endpoint[_] + conn := pe.private_service_connection + check_resource_id(conn.private_connection_resource_id, target_id) + ] + + count(private_endpoints) == 0 + + result := { + "documentId": doc.id, + "resourceType": resource_type, + "resourceName": tf_lib.get_resource_name(resource_instance, name), + "searchKey": sprintf("%s[%s]", [resource_type, name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'%s.%s' should be linked to an 'azurerm_private_endpoint'", [resource_type, name]), + "keyActualValue": sprintf("'%s.%s' is not linked to any 'azurerm_private_endpoint' in this file", [resource_type, name]), + } +} + +check_resource_id(current, target) { + current == target +} + +check_resource_id(current, target) { + current == sprintf("${%s}", [target]) +} diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json index 4ff2bbda593..bc8edc09dec 100644 --- a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-1038", "descriptionID": "bd3a6fc3", - "riskScore": 2.0 + "riskScore": "2.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego index 4433742de6c..8da9f5e92c1 100644 --- a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego @@ -1,34 +1,40 @@ -package Cx - -# REGLA 1: Azure Service Plan usando SKU Basic (B), Free (F) o Consumption (Y1). -CxPolicy[result] { - doc := input.document[i] - plan := doc.resource.azurerm_service_plan[name] - - invalid_skus := ["B1", "B2", "B3", "F1", "FREE", "Y1"] - plan.sku_name == invalid_skus[_] - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_service_plan.%s.sku_name", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("'%s.sku_name' should be Standard (S), Premium (P) or Isolated (I) for production", [name]), - "keyActualValue": sprintf("'%s.sku_name' is set to '%s' (Basic/Free/Consumption)", [name, plan.sku_name]), - } -} - -# REGLA 2: Azure API Management usando SKU Basic o Consumption. -CxPolicy[result] { - doc := input.document[i] - apim := doc.resource.azurerm_api_management[name] - - regex.match("(Basic|Consumption).*", apim.sku_name) - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_api_management.%s.sku_name", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("'%s.sku_name' should be Standard or Premium for production features", [name]), - "keyActualValue": sprintf("'%s.sku_name' is set to '%s'", [name, apim.sku_name]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Azure Service Plan usando SKU Basic (B), Free (F) o Consumption (Y1). +CxPolicy[result] { + doc := input.document[i] + plan := doc.resource.azurerm_service_plan[name] + + invalid_skus := ["B1", "B2", "B3", "F1", "FREE", "Y1"] + plan.sku_name == invalid_skus[_] + + result := { + "documentId": doc.id, + "resourceType": "azurerm_service_plan", + "resourceName": tf_lib.get_resource_name(plan, name), + "searchKey": sprintf("azurerm_service_plan[%s].sku_name", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": sprintf("'%s.sku_name' should be Standard (S), Premium (P) or Isolated (I) for production", [name]), + "keyActualValue": sprintf("'%s.sku_name' is set to '%s' (Basic/Free/Consumption)", [name, plan.sku_name]), + } +} + +# REGLA 2: Azure API Management usando SKU Basic o Consumption. +CxPolicy[result] { + doc := input.document[i] + apim := doc.resource.azurerm_api_management[name] + + regex.match("(Basic|Consumption).*", apim.sku_name) + + result := { + "documentId": doc.id, + "resourceType": "azurerm_api_management", + "resourceName": tf_lib.get_resource_name(apim, name), + "searchKey": sprintf("azurerm_api_management[%s].sku_name", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": sprintf("'%s.sku_name' should be Standard or Premium for production features", [name]), + "keyActualValue": sprintf("'%s.sku_name' is set to '%s'", [name, apim.sku_name]), + } +} diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json index 588fbca70b7..5c419b027ff 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-326", "descriptionID": "9436d439", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego index 3926d795315..05df1852299 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego @@ -1,17 +1,21 @@ -package Cx - -# REGLA 1: El bloque de encriptación no está definido. -CxPolicy[result] { - doc := input.document[i] - vault := doc.resource.azurerm_recovery_services_vault[name] - - not vault.encryption - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_recovery_services_vault.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_recovery_services_vault.%s' should have an 'encryption' block defined with a valid 'key_id'", [name]), - "keyActualValue": sprintf("'azurerm_recovery_services_vault.%s' is missing the 'encryption' block (Platform-Managed Keys by default)", [name]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: El bloque de encriptación no está definido. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_recovery_services_vault[name] + + not vault.encryption + + result := { + "documentId": doc.id, + "resourceType": "azurerm_recovery_services_vault", + "resourceName": tf_lib.get_resource_name(vault, name), + "searchKey": sprintf("azurerm_recovery_services_vault[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_recovery_services_vault.%s' should have an 'encryption' block defined with a valid 'key_id'", [name]), + "keyActualValue": sprintf("'azurerm_recovery_services_vault.%s' is missing the 'encryption' block (Platform-Managed Keys by default)", [name]), + } +} diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json index 5714b398bc0..a22b92d63c6 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-668", "descriptionID": "b7b0bc16", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego index bb16333f81d..e07bf3e96bf 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego @@ -1,33 +1,39 @@ -package Cx - -# REGLA 1: Atributo 'cross_region_restore_enabled' ausente. -CxPolicy[result] { - doc := input.document[i] - vault := doc.resource.azurerm_recovery_services_vault[name] - - object.get(vault, "cross_region_restore_enabled", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_recovery_services_vault.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_recovery_services_vault.%s' should have 'cross_region_restore_enabled' set to true", [name]), - "keyActualValue": sprintf("'azurerm_recovery_services_vault.%s' is missing 'cross_region_restore_enabled'", [name]), - } -} - -# REGLA 2: Atributo 'cross_region_restore_enabled' establecido en false. -CxPolicy[result] { - doc := input.document[i] - vault := doc.resource.azurerm_recovery_services_vault[name] - - vault.cross_region_restore_enabled == false - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_recovery_services_vault.%s.cross_region_restore_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'cross_region_restore_enabled' should be set to true", - "keyActualValue": "'cross_region_restore_enabled' is set to false", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Atributo 'cross_region_restore_enabled' ausente. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_recovery_services_vault[name] + + object.get(vault, "cross_region_restore_enabled", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "resourceType": "azurerm_recovery_services_vault", + "resourceName": tf_lib.get_resource_name(vault, name), + "searchKey": sprintf("azurerm_recovery_services_vault[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_recovery_services_vault.%s' should have 'cross_region_restore_enabled' set to true", [name]), + "keyActualValue": sprintf("'azurerm_recovery_services_vault.%s' is missing 'cross_region_restore_enabled'", [name]), + } +} + +# REGLA 2: Atributo 'cross_region_restore_enabled' establecido en false. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_recovery_services_vault[name] + + vault.cross_region_restore_enabled == false + + result := { + "documentId": doc.id, + "resourceType": "azurerm_recovery_services_vault", + "resourceName": tf_lib.get_resource_name(vault, name), + "searchKey": sprintf("azurerm_recovery_services_vault[%s].cross_region_restore_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'cross_region_restore_enabled' should be set to true", + "keyActualValue": "'cross_region_restore_enabled' is set to false", + } +} diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json index 44dd19a744d..b8b0f0581e1 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-312", "descriptionID": "95e32d9c", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego index bbdfc81beaf..198780181f1 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego @@ -1,34 +1,40 @@ -package Cx - -# REGLA 1: El bloque 'encryption' no está definido. -CxPolicy[result] { - doc := input.document[i] - vault := doc.resource.azurerm_recovery_services_vault[name] - - not vault.encryption - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_recovery_services_vault.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_recovery_services_vault.%s' should have an 'encryption' block defined", [name]), - "keyActualValue": sprintf("'azurerm_recovery_services_vault.%s' is missing the 'encryption' block", [name]), - } -} - -# REGLA 2: El atributo 'infrastructure_encryption_enabled' no está en true. -CxPolicy[result] { - doc := input.document[i] - vault := doc.resource.azurerm_recovery_services_vault[name] - - vault.encryption - object.get(vault.encryption, "infrastructure_encryption_enabled", false) != true - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_recovery_services_vault.%s.encryption.infrastructure_encryption_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "encryption.infrastructure_encryption_enabled should be set to true", - "keyActualValue": sprintf("encryption.infrastructure_encryption_enabled is set to %v", [object.get(vault.encryption, "infrastructure_encryption_enabled", false)]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: El bloque 'encryption' no está definido. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_recovery_services_vault[name] + + not vault.encryption + + result := { + "documentId": doc.id, + "resourceType": "azurerm_recovery_services_vault", + "resourceName": tf_lib.get_resource_name(vault, name), + "searchKey": sprintf("azurerm_recovery_services_vault[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_recovery_services_vault.%s' should have an 'encryption' block defined", [name]), + "keyActualValue": sprintf("'azurerm_recovery_services_vault.%s' is missing the 'encryption' block", [name]), + } +} + +# REGLA 2: El atributo 'infrastructure_encryption_enabled' no está en true. +CxPolicy[result] { + doc := input.document[i] + vault := doc.resource.azurerm_recovery_services_vault[name] + + vault.encryption + object.get(vault.encryption, "infrastructure_encryption_enabled", false) != true + + result := { + "documentId": doc.id, + "resourceType": "azurerm_recovery_services_vault", + "resourceName": tf_lib.get_resource_name(vault, name), + "searchKey": sprintf("azurerm_recovery_services_vault[%s].encryption.infrastructure_encryption_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "encryption.infrastructure_encryption_enabled should be set to true", + "keyActualValue": sprintf("encryption.infrastructure_encryption_enabled is set to %v", [object.get(vault.encryption, "infrastructure_encryption_enabled", false)]), + } +} diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json index 8047f2f55df..7af9efd6682 100644 --- a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-326", "descriptionID": "745e82b3", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego index 22c9b17da63..224c2f7dd51 100644 --- a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego @@ -1,32 +1,36 @@ -package Cx - -has_cmk_tde(doc, server_id) { - tde := doc.resource.azurerm_mssql_server_transparent_data_encryption[_] - check_id(tde.server_id, server_id) - tde.key_vault_key_id -} - -check_id(current, target) { - current == target -} - -check_id(current, target) { - current == sprintf("${%s}", [target]) -} - -# REGLA 1: SQL Server sin configuración de TDE explícita o sin CMK. -CxPolicy[result] { - doc := input.document[i] - server := doc.resource.azurerm_mssql_server[name] - server_id := sprintf("azurerm_mssql_server.%s.id", [name]) - - not has_cmk_tde(doc, server_id) - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_mssql_server.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_mssql_server.%s' should have an associated 'azurerm_mssql_server_transparent_data_encryption' resource with 'key_vault_key_id' set", [name]), - "keyActualValue": sprintf("'azurerm_mssql_server.%s' is using Service-Managed Key (default) or lacks TDE resource", [name]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +has_cmk_tde(doc, server_id) { + tde := doc.resource.azurerm_mssql_server_transparent_data_encryption[_] + check_id(tde.server_id, server_id) + tde.key_vault_key_id +} + +check_id(current, target) { + current == target +} + +check_id(current, target) { + current == sprintf("${%s}", [target]) +} + +# REGLA 1: SQL Server sin configuración de TDE explícita o sin CMK. +CxPolicy[result] { + doc := input.document[i] + server := doc.resource.azurerm_mssql_server[name] + server_id := sprintf("azurerm_mssql_server.%s.id", [name]) + + not has_cmk_tde(doc, server_id) + + result := { + "documentId": doc.id, + "resourceType": "azurerm_mssql_server", + "resourceName": tf_lib.get_resource_name(server, name), + "searchKey": sprintf("azurerm_mssql_server[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_mssql_server.%s' should have an associated 'azurerm_mssql_server_transparent_data_encryption' resource with 'key_vault_key_id' set", [name]), + "keyActualValue": sprintf("'azurerm_mssql_server.%s' is using Service-Managed Key (default) or lacks TDE resource", [name]), + } +} diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json index 7c5d7efb00d..802722e8f3d 100644 --- a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-668", "descriptionID": "56c748b8", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego index daa11248e5c..e6ab72bdac2 100644 --- a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego @@ -1,21 +1,25 @@ -package Cx - -geo_redundant_types := {"GRS", "RAGRS", "GZRS", "RAGZRS"} - -# REGLA 1: El tipo de replicación no es Geo-Redundante (ej. es LRS o ZRS). -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[name] - - current_type := sa.account_replication_type - - not geo_redundant_types[current_type] - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account.%s.account_replication_type", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'account_replication_type' should be 'GRS', 'RAGRS', 'GZRS', or 'RAGZRS'", - "keyActualValue": sprintf("'account_replication_type' is set to '%s'", [current_type]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +geo_redundant_types := {"GRS", "RAGRS", "GZRS", "RAGZRS"} + +# REGLA 1: El tipo de replicación no es Geo-Redundante (ej. es LRS o ZRS). +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + current_type := sa.account_replication_type + + not geo_redundant_types[current_type] + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account", + "resourceName": tf_lib.get_resource_name(sa, name), + "searchKey": sprintf("azurerm_storage_account[%s].account_replication_type", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'account_replication_type' should be 'GRS', 'RAGRS', 'GZRS', or 'RAGZRS'", + "keyActualValue": sprintf("'account_replication_type' is set to '%s'", [current_type]), + } +} diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json index 4b988f9c413..80e27e741fd 100644 --- a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-312", "descriptionID": "d02793e5", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego index 149bbed7e9f..cc2460acdb6 100644 --- a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego @@ -1,33 +1,39 @@ -package Cx - -# REGLA 1: Atributo 'infrastructure_encryption_enabled' ausente. -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[name] - - object.get(sa, "infrastructure_encryption_enabled", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have 'infrastructure_encryption_enabled' set to true", [name]), - "keyActualValue": sprintf("'azurerm_storage_account.%s' is missing 'infrastructure_encryption_enabled'", [name]), - } -} - -# REGLA 2: Atributo 'infrastructure_encryption_enabled' establecido en false. -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[name] - - sa.infrastructure_encryption_enabled == false - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account.%s.infrastructure_encryption_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'infrastructure_encryption_enabled' should be set to true", - "keyActualValue": "'infrastructure_encryption_enabled' is set to false", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Atributo 'infrastructure_encryption_enabled' ausente. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + object.get(sa, "infrastructure_encryption_enabled", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account", + "resourceName": tf_lib.get_resource_name(sa, name), + "searchKey": sprintf("azurerm_storage_account[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have 'infrastructure_encryption_enabled' set to true", [name]), + "keyActualValue": sprintf("'azurerm_storage_account.%s' is missing 'infrastructure_encryption_enabled'", [name]), + } +} + +# REGLA 2: Atributo 'infrastructure_encryption_enabled' establecido en false. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + sa.infrastructure_encryption_enabled == false + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account", + "resourceName": tf_lib.get_resource_name(sa, name), + "searchKey": sprintf("azurerm_storage_account[%s].infrastructure_encryption_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'infrastructure_encryption_enabled' should be set to true", + "keyActualValue": "'infrastructure_encryption_enabled' is set to false", + } +} diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json index 99fa66216c4..47f3e578d38 100644 --- a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-400", "descriptionID": "3a716202", - "riskScore": 2.0 + "riskScore": "2.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego index 560db7a509c..3b454baa130 100644 --- a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego @@ -1,58 +1,64 @@ -package Cx - -has_readonly_lock(doc, sa_id) { - l := doc.resource.azurerm_management_lock[_] - check_lock_scope(l.scope, sa_id) - l.lock_level == "ReadOnly" -} - -check_lock_scope(current, target) { - current == target -} - -check_lock_scope(current, target) { - current == sprintf("${%s}", [target]) -} - -# CASO 1: Storage Account totalmente desprotegido (sin bloqueos asociados) -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[sa_name] - sa_id := sprintf("azurerm_storage_account.%s.id", [sa_name]) - - associated_locks := [l | - l := doc.resource.azurerm_management_lock[_] - check_lock_scope(l.scope, sa_id) - ] - count(associated_locks) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account.%s", [sa_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have a 'ReadOnly' lock associated", [sa_name]), - "keyActualValue": sprintf("'azurerm_storage_account.%s' has no locks associated", [sa_name]), - } -} - -# CASO 2: Storage Account con bloqueo incorrecto (nivel distinto a ReadOnly) -CxPolicy[result] { - doc := input.document[i] - lock := doc.resource.azurerm_management_lock[lock_name] - - lock.lock_level != "ReadOnly" - - sa := doc.resource.azurerm_storage_account[sa_name] - sa_id := sprintf("azurerm_storage_account.%s.id", [sa_name]) - check_lock_scope(lock.scope, sa_id) - - not has_readonly_lock(doc, sa_id) - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_management_lock.%s.lock_level", [lock_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("'azurerm_management_lock.%s.lock_level' should be 'ReadOnly'", [lock_name]), - "keyActualValue": sprintf("'azurerm_management_lock.%s.lock_level' is '%s'", [lock_name, lock.lock_level]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +has_readonly_lock(doc, sa_id) { + l := doc.resource.azurerm_management_lock[_] + check_lock_scope(l.scope, sa_id) + l.lock_level == "ReadOnly" +} + +check_lock_scope(current, target) { + current == target +} + +check_lock_scope(current, target) { + current == sprintf("${%s}", [target]) +} + +# CASO 1: Storage Account totalmente desprotegido (sin bloqueos asociados) +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[sa_name] + sa_id := sprintf("azurerm_storage_account.%s.id", [sa_name]) + + associated_locks := [l | + l := doc.resource.azurerm_management_lock[_] + check_lock_scope(l.scope, sa_id) + ] + count(associated_locks) == 0 + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account", + "resourceName": tf_lib.get_resource_name(sa, sa_name), + "searchKey": sprintf("azurerm_storage_account[%s]", [sa_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have a 'ReadOnly' lock associated", [sa_name]), + "keyActualValue": sprintf("'azurerm_storage_account.%s' has no locks associated", [sa_name]), + } +} + +# CASO 2: Storage Account con bloqueo incorrecto (nivel distinto a ReadOnly) +CxPolicy[result] { + doc := input.document[i] + lock := doc.resource.azurerm_management_lock[lock_name] + + lock.lock_level != "ReadOnly" + + sa := doc.resource.azurerm_storage_account[sa_name] + sa_id := sprintf("azurerm_storage_account.%s.id", [sa_name]) + check_lock_scope(lock.scope, sa_id) + + not has_readonly_lock(doc, sa_id) + + result := { + "documentId": doc.id, + "resourceType": "azurerm_management_lock", + "resourceName": tf_lib.get_resource_name(lock, lock_name), + "searchKey": sprintf("azurerm_management_lock[%s].lock_level", [lock_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": sprintf("'azurerm_management_lock.%s.lock_level' should be 'ReadOnly'", [lock_name]), + "keyActualValue": sprintf("'azurerm_management_lock.%s.lock_level' is '%s'", [lock_name, lock.lock_level]), + } +} diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json index 88efc35cafb..808f5d040b1 100644 --- a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-226", "descriptionID": "0f437572", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego index 70bc0f27b04..b46220cd9d7 100644 --- a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego @@ -1,51 +1,59 @@ -package Cx - -# CASO 1: Falta el bloque 'blob_properties' completo. -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[name] - - not sa.blob_properties - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have 'blob_properties' defined", [name]), - "keyActualValue": sprintf("'azurerm_storage_account.%s' is missing 'blob_properties'", [name]), - } -} - -# CASO 2: Existe 'blob_properties' pero falta el atributo 'versioning_enabled'. -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[name] - - sa.blob_properties - - object.get(sa.blob_properties, "versioning_enabled", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account.%s.blob_properties", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "blob_properties.versioning_enabled should be defined and set to true", - "keyActualValue": "blob_properties.versioning_enabled is missing", - } -} - -# CASO 3: 'versioning_enabled' existe pero está explícitamente a false. -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[name] - - sa.blob_properties.versioning_enabled == false - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account.%s.blob_properties.versioning_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "blob_properties.versioning_enabled should be set to true", - "keyActualValue": "blob_properties.versioning_enabled is set to false", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# CASO 1: Falta el bloque 'blob_properties' completo. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + not sa.blob_properties + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account", + "resourceName": tf_lib.get_resource_name(sa, name), + "searchKey": sprintf("azurerm_storage_account[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have 'blob_properties' defined", [name]), + "keyActualValue": sprintf("'azurerm_storage_account.%s' is missing 'blob_properties'", [name]), + } +} + +# CASO 2: Existe 'blob_properties' pero falta el atributo 'versioning_enabled'. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + sa.blob_properties + + object.get(sa.blob_properties, "versioning_enabled", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account", + "resourceName": tf_lib.get_resource_name(sa, name), + "searchKey": sprintf("azurerm_storage_account[%s].blob_properties", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "blob_properties.versioning_enabled should be defined and set to true", + "keyActualValue": "blob_properties.versioning_enabled is missing", + } +} + +# CASO 3: 'versioning_enabled' existe pero está explícitamente a false. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + sa.blob_properties.versioning_enabled == false + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account", + "resourceName": tf_lib.get_resource_name(sa, name), + "searchKey": sprintf("azurerm_storage_account[%s].blob_properties.versioning_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "blob_properties.versioning_enabled should be set to true", + "keyActualValue": "blob_properties.versioning_enabled is set to false", + } +} diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json index 6433e6ca03d..1856f0d8d87 100644 --- a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-778", "descriptionID": "11fa88c0", - "riskScore": 2.0 + "riskScore": "2.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego index 1580109acde..a8f59e66791 100644 --- a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego @@ -1,76 +1,84 @@ -package Cx - -is_target_linked(target, sa_name) { - ref := sprintf("azurerm_storage_account.%s.id", [sa_name]) - contains(target, ref) - contains(target, "blobServices/default") -} - -is_target_linked(target, sa_name) { - ref := sprintf("${azurerm_storage_account.%s.id}", [sa_name]) - contains(target, ref) - contains(target, "blobServices/default") -} - -# CASO 1: La cuenta de almacenamiento no tiene ningún Diagnostic Setting para Blobs. -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[name] - - not diag_exists_for_sa(doc, name) - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have an 'azurerm_monitor_diagnostic_setting' for its blob service", [name]), - "keyActualValue": sprintf("'azurerm_storage_account.%s' does not have diagnostic logging enabled for blobs", [name]), - } -} - -diag_exists_for_sa(doc, sa_name) { - diag := doc.resource.azurerm_monitor_diagnostic_setting[_] - is_target_linked(diag.target_resource_id, sa_name) -} - -# CASO 2: El Diagnostic Setting existe pero no tiene ningún bloque 'enabled_log'. -CxPolicy[result] { - doc := input.document[i] - diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] - - contains(diag.target_resource_id, "blobServices/default") - not diag.enabled_log - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_monitor_diagnostic_setting.%s", [diag_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "Diagnostic Setting should have 'enabled_log' blocks defined", - "keyActualValue": "Diagnostic Setting has no 'enabled_log' blocks", - } -} - -# CASO 3: El Diagnostic Setting tiene bloques 'enabled_log' pero el conjunto está incompleto. -CxPolicy[result] { - doc := input.document[i] - diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] - - contains(diag.target_resource_id, "blobServices/default") - diag.enabled_log - - required_categories := {"StorageRead", "StorageWrite", "StorageDelete"} - present_categories := {cat | - log := diag.enabled_log[_] - cat := log.category - } - - not count(required_categories - present_categories) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_monitor_diagnostic_setting.%s.enabled_log", [diag_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "All required log categories (StorageRead, StorageWrite, StorageDelete) should be present", - "keyActualValue": "One or more required log categories are missing in the 'enabled_log' configuration", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +is_target_linked(target, sa_name) { + ref := sprintf("azurerm_storage_account.%s.id", [sa_name]) + contains(target, ref) + contains(target, "blobServices/default") +} + +is_target_linked(target, sa_name) { + ref := sprintf("${azurerm_storage_account.%s.id}", [sa_name]) + contains(target, ref) + contains(target, "blobServices/default") +} + +# CASO 1: La cuenta de almacenamiento no tiene ningún Diagnostic Setting para Blobs. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + not diag_exists_for_sa(doc, name) + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account", + "resourceName": tf_lib.get_resource_name(sa, name), + "searchKey": sprintf("azurerm_storage_account[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have an 'azurerm_monitor_diagnostic_setting' for its blob service", [name]), + "keyActualValue": sprintf("'azurerm_storage_account.%s' does not have diagnostic logging enabled for blobs", [name]), + } +} + +diag_exists_for_sa(doc, sa_name) { + diag := doc.resource.azurerm_monitor_diagnostic_setting[_] + is_target_linked(diag.target_resource_id, sa_name) +} + +# CASO 2: El Diagnostic Setting existe pero no tiene ningún bloque 'enabled_log'. +CxPolicy[result] { + doc := input.document[i] + diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] + + contains(diag.target_resource_id, "blobServices/default") + not diag.enabled_log + + result := { + "documentId": doc.id, + "resourceType": "azurerm_monitor_diagnostic_setting", + "resourceName": tf_lib.get_resource_name(diag, diag_name), + "searchKey": sprintf("azurerm_monitor_diagnostic_setting[%s]", [diag_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "Diagnostic Setting should have 'enabled_log' blocks defined", + "keyActualValue": "Diagnostic Setting has no 'enabled_log' blocks", + } +} + +# CASO 3: El Diagnostic Setting tiene bloques 'enabled_log' pero el conjunto está incompleto. +CxPolicy[result] { + doc := input.document[i] + diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] + + contains(diag.target_resource_id, "blobServices/default") + diag.enabled_log + + required_categories := {"StorageRead", "StorageWrite", "StorageDelete"} + present_categories := {cat | + log := diag.enabled_log[_] + cat := log.category + } + + not count(required_categories - present_categories) == 0 + + result := { + "documentId": doc.id, + "resourceType": "azurerm_monitor_diagnostic_setting", + "resourceName": tf_lib.get_resource_name(diag, diag_name), + "searchKey": sprintf("azurerm_monitor_diagnostic_setting[%s].enabled_log", [diag_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "All required log categories (StorageRead, StorageWrite, StorageDelete) should be present", + "keyActualValue": "One or more required log categories are missing in the 'enabled_log' configuration", + } +} diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json index eaf61fafe48..8721a47bf2a 100644 --- a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-284", "descriptionID": "9b959753", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego index 233dc06fe1c..4994a66b173 100644 --- a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego @@ -1,33 +1,39 @@ -package Cx - -# REGLA 1: El atributo 'locked' no está definido (Default es false/unlocked). -CxPolicy[result] { - doc := input.document[i] - policy := doc.resource.azurerm_storage_container_immutability_policy[name] - - object.get(policy, "locked", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_container_immutability_policy.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_storage_container_immutability_policy.%s' should have 'locked' set to true", [name]), - "keyActualValue": sprintf("'azurerm_storage_container_immutability_policy.%s' is missing 'locked' attribute (default is false)", [name]), - } -} - -# REGLA 2: El atributo 'locked' está explícitamente a false. -CxPolicy[result] { - doc := input.document[i] - policy := doc.resource.azurerm_storage_container_immutability_policy[name] - - policy.locked == false - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_container_immutability_policy.%s.locked", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'locked' should be set to true", - "keyActualValue": "'locked' is set to false", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: El atributo 'locked' no está definido (Default es false/unlocked). +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.azurerm_storage_container_immutability_policy[name] + + object.get(policy, "locked", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_container_immutability_policy", + "resourceName": tf_lib.get_resource_name(policy, name), + "searchKey": sprintf("azurerm_storage_container_immutability_policy[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_storage_container_immutability_policy.%s' should have 'locked' set to true", [name]), + "keyActualValue": sprintf("'azurerm_storage_container_immutability_policy.%s' is missing 'locked' attribute (default is false)", [name]), + } +} + +# REGLA 2: El atributo 'locked' está explícitamente a false. +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.azurerm_storage_container_immutability_policy[name] + + policy.locked == false + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_container_immutability_policy", + "resourceName": tf_lib.get_resource_name(policy, name), + "searchKey": sprintf("azurerm_storage_container_immutability_policy[%s].locked", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'locked' should be set to true", + "keyActualValue": "'locked' is set to false", + } +} diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json index 0c21a11ee0b..2fdd8d5d5f7 100644 --- a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-312", "descriptionID": "20fcb3ef", - "riskScore": 0.0 + "riskScore": "0.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego index e888549ca7b..49fb3983e7d 100644 --- a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego +++ b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego @@ -1,34 +1,40 @@ -package Cx - -# REGLA 1: El bloque 'customer_managed_key' no existe. -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[name] - - not sa.customer_managed_key - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should use CMK if hosting critical data (Manual Verification)", [name]), - "keyActualValue": sprintf("'azurerm_storage_account.%s' is using Platform-Managed Keys", [name]), - } -} - -# REGLA 2: El bloque existe pero el atributo 'key_vault_key_id' no está definido. -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[name] - - sa.customer_managed_key - object.get(sa.customer_managed_key, "key_vault_key_id", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account.%s.customer_managed_key", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "If 'customer_managed_key' block is defined, it should include 'key_vault_key_id' for CMK encryption", - "keyActualValue": "'key_vault_key_id' is not defined within the 'customer_managed_key' block", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: El bloque 'customer_managed_key' no existe. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + not sa.customer_managed_key + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account", + "resourceName": tf_lib.get_resource_name(sa, name), + "searchKey": sprintf("azurerm_storage_account[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should use CMK if hosting critical data (Manual Verification)", [name]), + "keyActualValue": sprintf("'azurerm_storage_account.%s' is using Platform-Managed Keys", [name]), + } +} + +# REGLA 2: El bloque existe pero el atributo 'key_vault_key_id' no está definido. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + sa.customer_managed_key + object.get(sa.customer_managed_key, "key_vault_key_id", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account", + "resourceName": tf_lib.get_resource_name(sa, name), + "searchKey": sprintf("azurerm_storage_account[%s].customer_managed_key", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "If 'customer_managed_key' block is defined, it should include 'key_vault_key_id' for CMK encryption", + "keyActualValue": "'key_vault_key_id' is not defined within the 'customer_managed_key' block", + } +} diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json index 24c682371b3..6a397c44d81 100644 --- a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-778", "descriptionID": "cddbdd74", - "riskScore": 2.0 + "riskScore": "2.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego index 0c5fbe8a745..4301ed2999d 100644 --- a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego @@ -1,74 +1,84 @@ -package Cx - -is_logging_valid(logging) { - logging.read == true - logging.write == true - logging.delete == true -} - -# CASO 1: Bloque 'logging' ausente en 'queue_properties' de azurerm_storage_account. -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[name] - - sa.queue_properties - not sa.queue_properties.logging - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account.%s.queue_properties", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "queue_properties.logging should be defined with read, write, and delete enabled", - "keyActualValue": "queue_properties.logging is missing", - } -} - -# CASO 2: Configuración de 'logging' incorrecta en azurerm_storage_account. -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[name] - - logging := sa.queue_properties.logging - not is_logging_valid(logging) - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account.%s.queue_properties.logging", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "logging should have read, write, and delete set to true", - "keyActualValue": "logging has one or more required actions (read, write, delete) disabled", - } -} - -# CASO 3: Bloque 'logging' ausente en el recurso azurerm_storage_account_queue_properties. -CxPolicy[result] { - doc := input.document[i] - props := doc.resource.azurerm_storage_account_queue_properties[name] - - not props.logging - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account_queue_properties.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "logging block should be defined in queue properties", - "keyActualValue": "logging block is missing", - } -} - -# CASO 4: Configuración de 'logging' incorrecta en azurerm_storage_account_queue_properties. -CxPolicy[result] { - doc := input.document[i] - props := doc.resource.azurerm_storage_account_queue_properties[name] - - logging := props.logging - not is_logging_valid(logging) - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account_queue_properties.%s.logging", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "logging should have read, write, and delete set to true", - "keyActualValue": "logging is missing one or more required actions", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +is_logging_valid(logging) { + logging.read == true + logging.write == true + logging.delete == true +} + +# CASO 1: Bloque 'logging' ausente en 'queue_properties' de azurerm_storage_account. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + sa.queue_properties + not sa.queue_properties.logging + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account", + "resourceName": tf_lib.get_resource_name(sa, name), + "searchKey": sprintf("azurerm_storage_account[%s].queue_properties", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "queue_properties.logging should be defined with read, write, and delete enabled", + "keyActualValue": "queue_properties.logging is missing", + } +} + +# CASO 2: Configuración de 'logging' incorrecta en azurerm_storage_account. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + logging := sa.queue_properties.logging + not is_logging_valid(logging) + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account", + "resourceName": tf_lib.get_resource_name(sa, name), + "searchKey": sprintf("azurerm_storage_account[%s].queue_properties.logging", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "logging should have read, write, and delete set to true", + "keyActualValue": "logging has one or more required actions (read, write, delete) disabled", + } +} + +# CASO 3: Bloque 'logging' ausente en el recurso azurerm_storage_account_queue_properties. +CxPolicy[result] { + doc := input.document[i] + props := doc.resource.azurerm_storage_account_queue_properties[name] + + not props.logging + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account_queue_properties", + "resourceName": tf_lib.get_resource_name(props, name), + "searchKey": sprintf("azurerm_storage_account_queue_properties[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "logging block should be defined in queue properties", + "keyActualValue": "logging block is missing", + } +} + +# CASO 4: Configuración de 'logging' incorrecta en azurerm_storage_account_queue_properties. +CxPolicy[result] { + doc := input.document[i] + props := doc.resource.azurerm_storage_account_queue_properties[name] + + logging := props.logging + not is_logging_valid(logging) + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account_queue_properties", + "resourceName": tf_lib.get_resource_name(props, name), + "searchKey": sprintf("azurerm_storage_account_queue_properties[%s].logging", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "logging should have read, write, and delete set to true", + "keyActualValue": "logging is missing one or more required actions", + } +} diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json index 7ab0ddb59aa..0a4ecadcbdc 100644 --- a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json @@ -9,5 +9,5 @@ "cloudProvider": "azure", "cwe": "CWE-778", "descriptionID": "0d29e3cf", - "riskScore": 2.0 + "riskScore": "2.0" } \ No newline at end of file diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego index 0def7c4add9..f42e178f480 100644 --- a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego @@ -1,76 +1,84 @@ -package Cx - -is_target_linked(target, sa_name) { - ref := sprintf("azurerm_storage_account.%s.id", [sa_name]) - contains(target, ref) - contains(target, "tableServices/default") -} - -is_target_linked(target, sa_name) { - ref := sprintf("${azurerm_storage_account.%s.id}", [sa_name]) - contains(target, ref) - contains(target, "tableServices/default") -} - -# CASO 1: La cuenta de almacenamiento no tiene ningún Diagnostic Setting para Tablas. -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[name] - - not diag_exists_for_sa(doc, name) - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_storage_account.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have an 'azurerm_monitor_diagnostic_setting' for its table service", [name]), - "keyActualValue": sprintf("'azurerm_storage_account.%s' does not have diagnostic logging enabled for tables", [name]), - } -} - -diag_exists_for_sa(doc, sa_name) { - diag := doc.resource.azurerm_monitor_diagnostic_setting[_] - is_target_linked(diag.target_resource_id, sa_name) -} - -# CASO 2: El Diagnostic Setting existe pero no tiene ningún bloque 'enabled_log'. -CxPolicy[result] { - doc := input.document[i] - diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] - - contains(diag.target_resource_id, "tableServices/default") - not diag.enabled_log - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_monitor_diagnostic_setting.%s", [diag_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "Diagnostic Setting should have 'enabled_log' blocks defined", - "keyActualValue": "Diagnostic Setting has no 'enabled_log' blocks", - } -} - -# CASO 3: El Diagnostic Setting tiene bloques 'enabled_log' pero el conjunto está incompleto. -CxPolicy[result] { - doc := input.document[i] - diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] - - contains(diag.target_resource_id, "tableServices/default") - diag.enabled_log - - required_categories := {"StorageRead", "StorageWrite", "StorageDelete"} - present_categories := {cat | - log := diag.enabled_log[_] - cat := log.category - } - - not count(required_categories - present_categories) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.azurerm_monitor_diagnostic_setting.%s.enabled_log", [diag_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "All required log categories (StorageRead, StorageWrite, StorageDelete) should be present", - "keyActualValue": "One or more required log categories are missing in the 'enabled_log' configuration for Table service", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +is_target_linked(target, sa_name) { + ref := sprintf("azurerm_storage_account.%s.id", [sa_name]) + contains(target, ref) + contains(target, "tableServices/default") +} + +is_target_linked(target, sa_name) { + ref := sprintf("${azurerm_storage_account.%s.id}", [sa_name]) + contains(target, ref) + contains(target, "tableServices/default") +} + +# CASO 1: La cuenta de almacenamiento no tiene ningún Diagnostic Setting para Tablas. +CxPolicy[result] { + doc := input.document[i] + sa := doc.resource.azurerm_storage_account[name] + + not diag_exists_for_sa(doc, name) + + result := { + "documentId": doc.id, + "resourceType": "azurerm_storage_account", + "resourceName": tf_lib.get_resource_name(sa, name), + "searchKey": sprintf("azurerm_storage_account[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have an 'azurerm_monitor_diagnostic_setting' for its table service", [name]), + "keyActualValue": sprintf("'azurerm_storage_account.%s' does not have diagnostic logging enabled for tables", [name]), + } +} + +diag_exists_for_sa(doc, sa_name) { + diag := doc.resource.azurerm_monitor_diagnostic_setting[_] + is_target_linked(diag.target_resource_id, sa_name) +} + +# CASO 2: El Diagnostic Setting existe pero no tiene ningún bloque 'enabled_log'. +CxPolicy[result] { + doc := input.document[i] + diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] + + contains(diag.target_resource_id, "tableServices/default") + not diag.enabled_log + + result := { + "documentId": doc.id, + "resourceType": "azurerm_monitor_diagnostic_setting", + "resourceName": tf_lib.get_resource_name(diag, diag_name), + "searchKey": sprintf("azurerm_monitor_diagnostic_setting[%s]", [diag_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "Diagnostic Setting should have 'enabled_log' blocks defined", + "keyActualValue": "Diagnostic Setting has no 'enabled_log' blocks", + } +} + +# CASO 3: El Diagnostic Setting tiene bloques 'enabled_log' pero el conjunto está incompleto. +CxPolicy[result] { + doc := input.document[i] + diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] + + contains(diag.target_resource_id, "tableServices/default") + diag.enabled_log + + required_categories := {"StorageRead", "StorageWrite", "StorageDelete"} + present_categories := {cat | + log := diag.enabled_log[_] + cat := log.category + } + + not count(required_categories - present_categories) == 0 + + result := { + "documentId": doc.id, + "resourceType": "azurerm_monitor_diagnostic_setting", + "resourceName": tf_lib.get_resource_name(diag, diag_name), + "searchKey": sprintf("azurerm_monitor_diagnostic_setting[%s].enabled_log", [diag_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "All required log categories (StorageRead, StorageWrite, StorageDelete) should be present", + "keyActualValue": "One or more required log categories are missing in the 'enabled_log' configuration for Table service", + } +} diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json index 64cbcb48dff..ed307e448eb 100644 --- a/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "d7df9989", "cloudProvider": "gcp", "cwe": "CWE-284", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego b/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego index f6a7dfce92f..afc70b2e7cf 100644 --- a/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego @@ -1,38 +1,44 @@ -package Cx - -# CASO 1: Proyecto sin configuración de Access Approval. -CxPolicy[result] { - doc := input.document[i] - project := doc.resource.google_project[name] - - settings := [s | - s := doc.resource.google_access_approval_project_settings[_] - contains(s.project_id, name) - ] - - count(settings) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_project.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'google_project.%s' should have 'google_access_approval_project_settings' associated", [name]), - "keyActualValue": sprintf("'google_project.%s' does not have Access Approval configured", [name]), - } -} - -# CASO 2: Access Approval configurado pero sin servicios inscritos. -CxPolicy[result] { - doc := input.document[i] - settings := doc.resource.google_access_approval_project_settings[name] - - not settings.enrolled_services - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_access_approval_project_settings.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "Must have at least one 'enrolled_services' block defined", - "keyActualValue": "'enrolled_services' is missing", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# CASO 1: Proyecto sin configuración de Access Approval. +CxPolicy[result] { + doc := input.document[i] + project := doc.resource.google_project[name] + + settings := [s | + s := doc.resource.google_access_approval_project_settings[_] + contains(s.project_id, name) + ] + + count(settings) == 0 + + result := { + "documentId": doc.id, + "resourceType": "google_project", + "resourceName": tf_lib.get_resource_name(project, name), + "searchKey": sprintf("google_project[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'google_project.%s' should have 'google_access_approval_project_settings' associated", [name]), + "keyActualValue": sprintf("'google_project.%s' does not have Access Approval configured", [name]), + } +} + +# CASO 2: Access Approval configurado pero sin servicios inscritos. +CxPolicy[result] { + doc := input.document[i] + settings := doc.resource.google_access_approval_project_settings[name] + + not settings.enrolled_services + + result := { + "documentId": doc.id, + "resourceType": "google_access_approval_project_settings", + "resourceName": tf_lib.get_resource_name(settings, name), + "searchKey": sprintf("google_access_approval_project_settings[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "Must have at least one 'enrolled_services' block defined", + "keyActualValue": "'enrolled_services' is missing", + } +} diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json index e4a80048519..f7d03e3db5d 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "8097afd6", "cloudProvider": "gcp", "cwe": "CWE-284", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego index ad76b2d3db5..14b7ad5a894 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego @@ -1,34 +1,40 @@ -package Cx - -# CASO 1: No existe el bloque 'restrictions'. -CxPolicy[result] { - doc := input.document[i] - key := doc.resource.google_apikeys_key[name] - - not key.restrictions - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_apikeys_key.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'google_apikeys_key.%s' should have 'restrictions.api_targets' defined", [name]), - "keyActualValue": sprintf("'google_apikeys_key.%s' is missing the 'restrictions' block", [name]), - } -} - -# CASO 2: Existe 'restrictions', pero falta 'api_targets'. -CxPolicy[result] { - doc := input.document[i] - key := doc.resource.google_apikeys_key[name] - - key.restrictions - not key.restrictions.api_targets - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_apikeys_key.%s.restrictions", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "restrictions.api_targets should be defined", - "keyActualValue": "restrictions.api_targets is missing", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# CASO 1: No existe el bloque 'restrictions'. +CxPolicy[result] { + doc := input.document[i] + key := doc.resource.google_apikeys_key[name] + + not key.restrictions + + result := { + "documentId": doc.id, + "resourceType": "google_apikeys_key", + "resourceName": tf_lib.get_resource_name(key, name), + "searchKey": sprintf("google_apikeys_key[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'google_apikeys_key.%s' should have 'restrictions.api_targets' defined", [name]), + "keyActualValue": sprintf("'google_apikeys_key.%s' is missing the 'restrictions' block", [name]), + } +} + +# CASO 2: Existe 'restrictions', pero falta 'api_targets'. +CxPolicy[result] { + doc := input.document[i] + key := doc.resource.google_apikeys_key[name] + + key.restrictions + not key.restrictions.api_targets + + result := { + "documentId": doc.id, + "resourceType": "google_apikeys_key", + "resourceName": tf_lib.get_resource_name(key, name), + "searchKey": sprintf("google_apikeys_key[%s].restrictions", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "restrictions.api_targets should be defined", + "keyActualValue": "restrictions.api_targets is missing", + } +} diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json index a91205ab304..0e1d85897c0 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "7b3ba800", "cloudProvider": "gcp", "cwe": "CWE-284", - "riskScore": 0.0 + "riskScore": "0.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego index c3edd6d961b..775874fadec 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego @@ -1,33 +1,39 @@ -package Cx - -# CASO 1: No hay restricciones definidas. -CxPolicy[result] { - doc := input.document[i] - key := doc.resource.google_apikeys_key[name] - - not key.restrictions - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_apikeys_key.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'google_apikeys_key.%s' should have a 'restrictions' block defined", [name]), - "keyActualValue": sprintf("'google_apikeys_key.%s' is missing the 'restrictions' block", [name]), - } -} - -# CASO 2: Hay restricciones definidas. -CxPolicy[result] { - doc := input.document[i] - key := doc.resource.google_apikeys_key[name] - - key.restrictions - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_apikeys_key.%s.restrictions", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "Restrictions should be verified against allowed IPs/Referrers", - "keyActualValue": "Restrictions are present. Manual verification required.", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# CASO 1: No hay restricciones definidas. +CxPolicy[result] { + doc := input.document[i] + key := doc.resource.google_apikeys_key[name] + + not key.restrictions + + result := { + "documentId": doc.id, + "resourceType": "google_apikeys_key", + "resourceName": tf_lib.get_resource_name(key, name), + "searchKey": sprintf("google_apikeys_key[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'google_apikeys_key.%s' should have a 'restrictions' block defined", [name]), + "keyActualValue": sprintf("'google_apikeys_key.%s' is missing the 'restrictions' block", [name]), + } +} + +# CASO 2: Hay restricciones definidas. +CxPolicy[result] { + doc := input.document[i] + key := doc.resource.google_apikeys_key[name] + + key.restrictions + + result := { + "documentId": doc.id, + "resourceType": "google_apikeys_key", + "resourceName": tf_lib.get_resource_name(key, name), + "searchKey": sprintf("google_apikeys_key[%s].restrictions", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Restrictions should be verified against allowed IPs/Referrers", + "keyActualValue": "Restrictions are present. Manual verification required.", + } +} diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json index 38b32c311e5..71665ae005d 100644 --- a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "52b7bc15", "cloudProvider": "gcp", "cwe": "CWE-319", - "riskScore": 0.0 + "riskScore": "0.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego index 13dd18563ce..99bb9112a85 100644 --- a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego @@ -1,42 +1,48 @@ -package Cx - -ensure_array(x) = x { is_array(x) } -ensure_array(x) = [x] { not is_array(x) } - -# CASO 1: Configuración Insegura en los handlers definidos. -CxPolicy[result] { - doc := input.document[i] - app := doc.resource.google_app_engine_standard_app_version[name] - - app.handlers - - handlers_list := ensure_array(app.handlers) - handler := handlers_list[_] - - sec_level := object.get(handler, "security_level", "UNSPECIFIED") - sec_level != "SECURE_ALWAYS" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_app_engine_standard_app_version.%s.handlers", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'handlers.security_level' should be set to 'SECURE_ALWAYS'", - "keyActualValue": sprintf("'handlers.security_level' is set to '%s'", [sec_level]), - } -} - -# CASO 2: Configuración Ausente en Terraform (Requiere revisión de app.yaml). -CxPolicy[result] { - doc := input.document[i] - app := doc.resource.google_app_engine_standard_app_version[name] - - not app.handlers - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_app_engine_standard_app_version.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "If handlers are not defined in Terraform, verify 'app.yaml' contains 'secure: always'", - "keyActualValue": "Terraform does not define handlers. Manual verification of 'app.yaml' required.", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +ensure_array(x) = x { is_array(x) } +ensure_array(x) = [x] { not is_array(x) } + +# CASO 1: Configuración Insegura en los handlers definidos. +CxPolicy[result] { + doc := input.document[i] + app := doc.resource.google_app_engine_standard_app_version[name] + + app.handlers + + handlers_list := ensure_array(app.handlers) + handler := handlers_list[_] + + sec_level := object.get(handler, "security_level", "UNSPECIFIED") + sec_level != "SECURE_ALWAYS" + + result := { + "documentId": doc.id, + "resourceType": "google_app_engine_standard_app_version", + "resourceName": tf_lib.get_resource_name(app, name), + "searchKey": sprintf("google_app_engine_standard_app_version[%s].handlers", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'handlers.security_level' should be set to 'SECURE_ALWAYS'", + "keyActualValue": sprintf("'handlers.security_level' is set to '%s'", [sec_level]), + } +} + +# CASO 2: Configuración Ausente en Terraform (Requiere revisión de app.yaml). +CxPolicy[result] { + doc := input.document[i] + app := doc.resource.google_app_engine_standard_app_version[name] + + not app.handlers + + result := { + "documentId": doc.id, + "resourceType": "google_app_engine_standard_app_version", + "resourceName": tf_lib.get_resource_name(app, name), + "searchKey": sprintf("google_app_engine_standard_app_version[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "If handlers are not defined in Terraform, verify 'app.yaml' contains 'secure: always'", + "keyActualValue": "Terraform does not define handlers. Manual verification of 'app.yaml' required.", + } +} diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json index c2038150816..e61fd761d2f 100644 --- a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "ccefc589", "cloudProvider": "gcp", "cwe": "CWE-778", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego index c0f0b0534a6..9ffa856729b 100644 --- a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego @@ -1,51 +1,59 @@ -package Cx - -# REGLA 1: El bloque 'metadata' no existe. -CxPolicy[result] { - doc := input.document[i] - instance := doc.resource.google_compute_instance[name] - - not instance.metadata - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_compute_instance.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'metadata' block should be defined and contain 'google-logging-enabled'", - "keyActualValue": "'metadata' block is missing", - } -} - -# REGLA 2: El bloque 'metadata' existe pero le falta la clave 'google-logging-enabled'. -CxPolicy[result] { - doc := input.document[i] - instance := doc.resource.google_compute_instance[name] - - instance.metadata - not instance.metadata["google-logging-enabled"] - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_compute_instance.%s.metadata", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'google-logging-enabled' should be defined within metadata", - "keyActualValue": "'google-logging-enabled' is missing in metadata", - } -} - -# REGLA 3: La clave existe pero su valor es 'false'. -CxPolicy[result] { - doc := input.document[i] - instance := doc.resource.google_compute_instance[name] - - val := instance.metadata["google-logging-enabled"] - val == "false" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_compute_instance.%s.metadata.google-logging-enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'google-logging-enabled' should be set to 'true'", - "keyActualValue": "'google-logging-enabled' is set to 'false'", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: El bloque 'metadata' no existe. +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.google_compute_instance[name] + + not instance.metadata + + result := { + "documentId": doc.id, + "resourceType": "google_compute_instance", + "resourceName": tf_lib.get_resource_name(instance, name), + "searchKey": sprintf("google_compute_instance[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'metadata' block should be defined and contain 'google-logging-enabled'", + "keyActualValue": "'metadata' block is missing", + } +} + +# REGLA 2: El bloque 'metadata' existe pero le falta la clave 'google-logging-enabled'. +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.google_compute_instance[name] + + instance.metadata + not instance.metadata["google-logging-enabled"] + + result := { + "documentId": doc.id, + "resourceType": "google_compute_instance", + "resourceName": tf_lib.get_resource_name(instance, name), + "searchKey": sprintf("google_compute_instance[%s].metadata", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'google-logging-enabled' should be defined within metadata", + "keyActualValue": "'google-logging-enabled' is missing in metadata", + } +} + +# REGLA 3: La clave existe pero su valor es 'false'. +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.google_compute_instance[name] + + val := instance.metadata["google-logging-enabled"] + val == "false" + + result := { + "documentId": doc.id, + "resourceType": "google_compute_instance", + "resourceName": tf_lib.get_resource_name(instance, name), + "searchKey": sprintf("google_compute_instance[%s].metadata.google-logging-enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'google-logging-enabled' should be set to 'true'", + "keyActualValue": "'google-logging-enabled' is set to 'false'", + } +} diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json index 6fd64f265d2..1e34cb0e1c0 100644 --- a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "8ef3f681", "cloudProvider": "gcp", "cwe": "CWE-276", - "riskScore": 9.0 + "riskScore": "9.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego index ecb14c5bfcc..b9ceb1e587f 100644 --- a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego @@ -1,33 +1,39 @@ -package Cx - -# REGLA 1: Service Account ausente en google_container_cluster. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_container_cluster[name] - - not resource.node_config.service_account - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s.node_config", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'service_account' should be explicitly defined in node_config", - "keyActualValue": "'service_account' is missing, defaulting to the Compute Engine default service account", - } -} - -# REGLA 2: Service Account ausente en google_container_node_pool. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_container_node_pool[name] - - not resource.node_config.service_account - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_node_pool.%s.node_config", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'service_account' should be explicitly defined in node_config", - "keyActualValue": "'service_account' is missing, defaulting to the Compute Engine default service account", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Service Account ausente en google_container_cluster. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_cluster[name] + + not resource.node_config.service_account + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_container_cluster[%s].node_config", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'service_account' should be explicitly defined in node_config", + "keyActualValue": "'service_account' is missing, defaulting to the Compute Engine default service account", + } +} + +# REGLA 2: Service Account ausente en google_container_node_pool. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_node_pool[name] + + not resource.node_config.service_account + + result := { + "documentId": doc.id, + "resourceType": "google_container_node_pool", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_container_node_pool[%s].node_config", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'service_account' should be explicitly defined in node_config", + "keyActualValue": "'service_account' is missing, defaulting to the Compute Engine default service account", + } +} diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json index 129e38d16fe..98d0c94186c 100644 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "30b5b4bb", "cloudProvider": "gcp", "cwe": "CWE-1395", - "riskScore": 9.0 + "riskScore": "9.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego index d3736459d35..c5017869da3 100644 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego @@ -1,51 +1,59 @@ -package Cx - -# REGLA 1: Bloque 'security_posture_config' ausente. -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - not cluster.security_posture_config - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'security_posture_config' block should be defined", - "keyActualValue": "'security_posture_config' block is missing", - } -} - -# REGLA 2: Atributo 'vulnerability_mode' ausente dentro del bloque. -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - cluster.security_posture_config - not cluster.security_posture_config.vulnerability_mode - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s.security_posture_config", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'vulnerability_mode' should be defined within security_posture_config", - "keyActualValue": "'vulnerability_mode' is missing", - } -} - -# REGLA 3: Atributo 'vulnerability_mode' configurado como 'VULNERABILITY_DISABLED'. -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - mode := cluster.security_posture_config.vulnerability_mode - mode == "VULNERABILITY_DISABLED" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s.security_posture_config.vulnerability_mode", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'vulnerability_mode' should be 'VULNERABILITY_BASIC' or 'VULNERABILITY_ENTERPRISE'", - "keyActualValue": "'vulnerability_mode' is set to 'VULNERABILITY_DISABLED'", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Bloque 'security_posture_config' ausente. +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + not cluster.security_posture_config + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(cluster, name), + "searchKey": sprintf("google_container_cluster[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'security_posture_config' block should be defined", + "keyActualValue": "'security_posture_config' block is missing", + } +} + +# REGLA 2: Atributo 'vulnerability_mode' ausente dentro del bloque. +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + cluster.security_posture_config + not cluster.security_posture_config.vulnerability_mode + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(cluster, name), + "searchKey": sprintf("google_container_cluster[%s].security_posture_config", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'vulnerability_mode' should be defined within security_posture_config", + "keyActualValue": "'vulnerability_mode' is missing", + } +} + +# REGLA 3: Atributo 'vulnerability_mode' configurado como 'VULNERABILITY_DISABLED'. +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + mode := cluster.security_posture_config.vulnerability_mode + mode == "VULNERABILITY_DISABLED" + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(cluster, name), + "searchKey": sprintf("google_container_cluster[%s].security_posture_config.vulnerability_mode", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'vulnerability_mode' should be 'VULNERABILITY_BASIC' or 'VULNERABILITY_ENTERPRISE'", + "keyActualValue": "'vulnerability_mode' is set to 'VULNERABILITY_DISABLED'", + } +} diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json index 5ace58c4a29..b554166f1d8 100644 --- a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "b29ff836", "cloudProvider": "gcp", "cwe": "CWE-276", - "riskScore": 0.0 + "riskScore": "0.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego index a3c5faa3751..7b9f30995d0 100644 --- a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego @@ -1,33 +1,39 @@ -package Cx - -# REGLA 1: Detección de SA personalizada en google_container_cluster. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_container_cluster[name] - - sa := resource.node_config.service_account - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s.node_config.service_account", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "Custom Service Account IAM roles should be verified as Read-Only", - "keyActualValue": sprintf("Custom Service Account '%s' found. Manual IAM verification required.", [sa]), - } -} - -# REGLA 2: Detección de SA personalizada en google_container_node_pool. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_container_node_pool[name] - - sa := resource.node_config.service_account - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_node_pool.%s.node_config.service_account", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "Custom Service Account IAM roles should be verified as Read-Only", - "keyActualValue": sprintf("Custom Service Account '%s' found. Manual IAM verification required.", [sa]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Detección de SA personalizada en google_container_cluster. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_cluster[name] + + sa := resource.node_config.service_account + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_container_cluster[%s].node_config.service_account", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Custom Service Account IAM roles should be verified as Read-Only", + "keyActualValue": sprintf("Custom Service Account '%s' found. Manual IAM verification required.", [sa]), + } +} + +# REGLA 2: Detección de SA personalizada en google_container_node_pool. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_node_pool[name] + + sa := resource.node_config.service_account + + result := { + "documentId": doc.id, + "resourceType": "google_container_node_pool", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_container_node_pool[%s].node_config.service_account", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Custom Service Account IAM roles should be verified as Read-Only", + "keyActualValue": sprintf("Custom Service Account '%s' found. Manual IAM verification required.", [sa]), + } +} diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json index e15967fcbb7..8d3b7f7228a 100644 --- a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "e858428b", "cloudProvider": "gcp", "cwe": "CWE-284", - "riskScore": 9.0 + "riskScore": "9.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego index d853b869a5c..039d2b33472 100644 --- a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego @@ -1,65 +1,75 @@ -package Cx - -# REGLA 1: 'workload_metadata_config' ausente en google_container_cluster -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_container_cluster[name] - - not resource.node_config.workload_metadata_config - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s.node_config", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'workload_metadata_config' should be defined with mode 'GKE_METADATA'", - "keyActualValue": "'workload_metadata_config' is missing", - } -} - -# REGLA 2: 'workload_metadata_config' ausente en google_container_node_pool -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_container_node_pool[name] - - not resource.node_config.workload_metadata_config - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_node_pool.%s.node_config", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'workload_metadata_config' should be defined with mode 'GKE_METADATA'", - "keyActualValue": "'workload_metadata_config' is missing", - } -} - -# REGLA 3: Modo incorrecto en google_container_cluster -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_container_cluster[name] - - resource.node_config.workload_metadata_config.mode != "GKE_METADATA" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s.node_config.workload_metadata_config.mode", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'mode' should be set to 'GKE_METADATA'", - "keyActualValue": sprintf("'mode' is set to '%s'", [resource.node_config.workload_metadata_config.mode]), - } -} - -# REGLA 4: Modo incorrecto en google_container_node_pool -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_container_node_pool[name] - - resource.node_config.workload_metadata_config.mode != "GKE_METADATA" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_node_pool.%s.node_config.workload_metadata_config.mode", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'mode' should be set to 'GKE_METADATA'", - "keyActualValue": sprintf("'mode' is set to '%s'", [resource.node_config.workload_metadata_config.mode]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: 'workload_metadata_config' ausente en google_container_cluster +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_cluster[name] + + not resource.node_config.workload_metadata_config + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_container_cluster[%s].node_config", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'workload_metadata_config' should be defined with mode 'GKE_METADATA'", + "keyActualValue": "'workload_metadata_config' is missing", + } +} + +# REGLA 2: 'workload_metadata_config' ausente en google_container_node_pool +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_node_pool[name] + + not resource.node_config.workload_metadata_config + + result := { + "documentId": doc.id, + "resourceType": "google_container_node_pool", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_container_node_pool[%s].node_config", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'workload_metadata_config' should be defined with mode 'GKE_METADATA'", + "keyActualValue": "'workload_metadata_config' is missing", + } +} + +# REGLA 3: Modo incorrecto en google_container_cluster +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_cluster[name] + + resource.node_config.workload_metadata_config.mode != "GKE_METADATA" + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_container_cluster[%s].node_config.workload_metadata_config.mode", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'mode' should be set to 'GKE_METADATA'", + "keyActualValue": sprintf("'mode' is set to '%s'", [resource.node_config.workload_metadata_config.mode]), + } +} + +# REGLA 4: Modo incorrecto en google_container_node_pool +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_node_pool[name] + + resource.node_config.workload_metadata_config.mode != "GKE_METADATA" + + result := { + "documentId": doc.id, + "resourceType": "google_container_node_pool", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_container_node_pool[%s].node_config.workload_metadata_config.mode", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'mode' should be set to 'GKE_METADATA'", + "keyActualValue": sprintf("'mode' is set to '%s'", [resource.node_config.workload_metadata_config.mode]), + } +} diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json index 327a2de5107..775e4ae2bf4 100644 --- a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "6c8a93a9", "cloudProvider": "gcp", "cwe": "CWE-1038", - "riskScore": 3.0 + "riskScore": "3.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego index 7a81e5cd947..dce3885c859 100644 --- a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego @@ -1,65 +1,75 @@ -package Cx - -# REGLA 1: Bloque 'sandbox_config' ausente en google_container_cluster. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_container_cluster[name] - - not resource.node_config.sandbox_config - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s.node_config", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'sandbox_config' should be defined with sandbox_type 'gvisor'", - "keyActualValue": "'sandbox_config' is missing", - } -} - -# REGLA 2: Bloque 'sandbox_config' ausente en google_container_node_pool. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_container_node_pool[name] - - not resource.node_config.sandbox_config - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_node_pool.%s.node_config", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'sandbox_config' should be defined with sandbox_type 'gvisor'", - "keyActualValue": "'sandbox_config' is missing", - } -} - -# REGLA 3: sandbox_type incorrecto en google_container_cluster. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_container_cluster[name] - - resource.node_config.sandbox_config.sandbox_type != "gvisor" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s.node_config.sandbox_config.sandbox_type", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'sandbox_type' should be 'gvisor'", - "keyActualValue": sprintf("'sandbox_type' is set to '%s'", [resource.node_config.sandbox_config.sandbox_type]), - } -} - -# REGLA 4: sandbox_type incorrecto en google_container_node_pool. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_container_node_pool[name] - - resource.node_config.sandbox_config.sandbox_type != "gvisor" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_node_pool.%s.node_config.sandbox_config.sandbox_type", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'sandbox_type' should be 'gvisor'", - "keyActualValue": sprintf("'sandbox_type' is set to '%s'", [resource.node_config.sandbox_config.sandbox_type]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Bloque 'sandbox_config' ausente en google_container_cluster. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_cluster[name] + + not resource.node_config.sandbox_config + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_container_cluster[%s].node_config", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'sandbox_config' should be defined with sandbox_type 'gvisor'", + "keyActualValue": "'sandbox_config' is missing", + } +} + +# REGLA 2: Bloque 'sandbox_config' ausente en google_container_node_pool. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_node_pool[name] + + not resource.node_config.sandbox_config + + result := { + "documentId": doc.id, + "resourceType": "google_container_node_pool", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_container_node_pool[%s].node_config", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'sandbox_config' should be defined with sandbox_type 'gvisor'", + "keyActualValue": "'sandbox_config' is missing", + } +} + +# REGLA 3: sandbox_type incorrecto en google_container_cluster. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_cluster[name] + + resource.node_config.sandbox_config.sandbox_type != "gvisor" + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_container_cluster[%s].node_config.sandbox_config.sandbox_type", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'sandbox_type' should be 'gvisor'", + "keyActualValue": sprintf("'sandbox_type' is set to '%s'", [resource.node_config.sandbox_config.sandbox_type]), + } +} + +# REGLA 4: sandbox_type incorrecto en google_container_node_pool. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_container_node_pool[name] + + resource.node_config.sandbox_config.sandbox_type != "gvisor" + + result := { + "documentId": doc.id, + "resourceType": "google_container_node_pool", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_container_node_pool[%s].node_config.sandbox_config.sandbox_type", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'sandbox_type' should be 'gvisor'", + "keyActualValue": sprintf("'sandbox_type' is set to '%s'", [resource.node_config.sandbox_config.sandbox_type]), + } +} diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json index e577ed16253..b0353ca7a29 100644 --- a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "83d1c89f", "cloudProvider": "gcp", "cwe": "CWE-312", - "riskScore": 9.0 + "riskScore": "9.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego index 65cce79b0e4..0b7e70b2178 100644 --- a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego @@ -1,52 +1,60 @@ -package Cx - -# REGLA 1: Bloque 'database_encryption' ausente. -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - not cluster.database_encryption - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'database_encryption' block should be defined", - "keyActualValue": "'database_encryption' block is missing", - } -} - -# REGLA 2: Estado de cifrado incorrecto (DECRYPTED). -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - cluster.database_encryption.state != "ENCRYPTED" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s.database_encryption.state", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'state' should be set to 'ENCRYPTED'", - "keyActualValue": sprintf("'state' is set to '%s'", [cluster.database_encryption.state]), - } -} - -# REGLA 3: Estado ENCRYPTED pero falta el nombre de la clave (key_name). -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - cluster.database_encryption.state == "ENCRYPTED" - - key_name := object.get(cluster.database_encryption, "key_name", "") - key_name == "" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s.database_encryption.key_name", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'key_name' should be defined with a valid KMS key ID", - "keyActualValue": "'key_name' is missing or empty", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Bloque 'database_encryption' ausente. +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + not cluster.database_encryption + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(cluster, name), + "searchKey": sprintf("google_container_cluster[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'database_encryption' block should be defined", + "keyActualValue": "'database_encryption' block is missing", + } +} + +# REGLA 2: Estado de cifrado incorrecto (DECRYPTED). +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + cluster.database_encryption.state != "ENCRYPTED" + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(cluster, name), + "searchKey": sprintf("google_container_cluster[%s].database_encryption.state", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'state' should be set to 'ENCRYPTED'", + "keyActualValue": sprintf("'state' is set to '%s'", [cluster.database_encryption.state]), + } +} + +# REGLA 3: Estado ENCRYPTED pero falta el nombre de la clave (key_name). +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + cluster.database_encryption.state == "ENCRYPTED" + + key_name := object.get(cluster.database_encryption, "key_name", "") + key_name == "" + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(cluster, name), + "searchKey": sprintf("google_container_cluster[%s].database_encryption.key_name", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'key_name' should be defined with a valid KMS key ID", + "keyActualValue": "'key_name' is missing or empty", + } +} diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json index a119b6d3e04..b5d56dace4c 100644 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "0d688e9b", "cloudProvider": "gcp", "cwe": "CWE-1038", - "riskScore": 0.0 + "riskScore": "0.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego index cfeb14b6cb9..a7bade30f23 100644 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego @@ -1,33 +1,39 @@ -package Cx - -# REGLA 1: Bloque 'security_posture_config' ausente. -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - not cluster.security_posture_config - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'security_posture_config' block should be defined with mode 'BASIC' or 'ENTERPRISE'", - "keyActualValue": "'security_posture_config' block is missing", - } -} - -# REGLA 2: Bloque presente, pero 'mode' es 'DISABLED'. -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - cluster.security_posture_config.mode == "DISABLED" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s.security_posture_config.mode", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'mode' should be set to 'BASIC' or 'ENTERPRISE'", - "keyActualValue": "'mode' is set to 'DISABLED'", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Bloque 'security_posture_config' ausente. +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + not cluster.security_posture_config + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(cluster, name), + "searchKey": sprintf("google_container_cluster[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'security_posture_config' block should be defined with mode 'BASIC' or 'ENTERPRISE'", + "keyActualValue": "'security_posture_config' block is missing", + } +} + +# REGLA 2: Bloque presente, pero 'mode' es 'DISABLED'. +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + cluster.security_posture_config.mode == "DISABLED" + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(cluster, name), + "searchKey": sprintf("google_container_cluster[%s].security_posture_config.mode", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'mode' should be set to 'BASIC' or 'ENTERPRISE'", + "keyActualValue": "'mode' is set to 'DISABLED'", + } +} diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json index fb66fe944b8..a936faa9f6f 100644 --- a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "edea054b", "cloudProvider": "gcp", "cwe": "CWE-284", - "riskScore": 0.0 + "riskScore": "0.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego index d10a078e579..5e1499fe702 100644 --- a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego @@ -1,33 +1,39 @@ -package Cx - -# REGLA 1: Workload Identity no habilitado (Missing Attribute). -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - not cluster.workload_identity_config - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'workload_identity_config' should be enabled to support dedicated Service Accounts", - "keyActualValue": "'workload_identity_config' is missing", - } -} - -# REGLA 2: Workload Identity habilitado (Verificación Manual de Bindings). -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - cluster.workload_identity_config - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_container_cluster.%s.workload_identity_config", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "Verify that workloads use dedicated Service Accounts (no shared SAs)", - "keyActualValue": "Workload Identity is enabled. Manual verification of bindings required.", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Workload Identity no habilitado (Missing Attribute). +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + not cluster.workload_identity_config + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(cluster, name), + "searchKey": sprintf("google_container_cluster[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'workload_identity_config' should be enabled to support dedicated Service Accounts", + "keyActualValue": "'workload_identity_config' is missing", + } +} + +# REGLA 2: Workload Identity habilitado (Verificación Manual de Bindings). +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.google_container_cluster[name] + + cluster.workload_identity_config + + result := { + "documentId": doc.id, + "resourceType": "google_container_cluster", + "resourceName": tf_lib.get_resource_name(cluster, name), + "searchKey": sprintf("google_container_cluster[%s].workload_identity_config", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Verify that workloads use dedicated Service Accounts (no shared SAs)", + "keyActualValue": "Workload Identity is enabled. Manual verification of bindings required.", + } +} diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json index 3e26bf5e632..3b02d6fc606 100644 --- a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "0ef3f3f1", "cloudProvider": "gcp", "cwe": "CWE-778", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego index e15697ad864..4477185b7c6 100644 --- a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego @@ -1,33 +1,39 @@ -package Cx - -# REGLA 1: Bloque 'log_config' ausente. -CxPolicy[result] { - doc := input.document[i] - bs := doc.resource.google_compute_backend_service[name] - - not bs.log_config - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_compute_backend_service.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "log_config should be defined with enable set to true", - "keyActualValue": "log_config is missing", - } -} - -# REGLA 2: Bloque 'log_config' existe pero 'enable' es false. -CxPolicy[result] { - doc := input.document[i] - bs := doc.resource.google_compute_backend_service[name] - - bs.log_config.enable == false - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_compute_backend_service.%s.log_config.enable", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "log_config.enable should be set to true", - "keyActualValue": "log_config.enable is set to false", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: Bloque 'log_config' ausente. +CxPolicy[result] { + doc := input.document[i] + bs := doc.resource.google_compute_backend_service[name] + + not bs.log_config + + result := { + "documentId": doc.id, + "resourceType": "google_compute_backend_service", + "resourceName": tf_lib.get_resource_name(bs, name), + "searchKey": sprintf("google_compute_backend_service[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "log_config should be defined with enable set to true", + "keyActualValue": "log_config is missing", + } +} + +# REGLA 2: Bloque 'log_config' existe pero 'enable' es false. +CxPolicy[result] { + doc := input.document[i] + bs := doc.resource.google_compute_backend_service[name] + + bs.log_config.enable == false + + result := { + "documentId": doc.id, + "resourceType": "google_compute_backend_service", + "resourceName": tf_lib.get_resource_name(bs, name), + "searchKey": sprintf("google_compute_backend_service[%s].log_config.enable", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "log_config.enable should be set to true", + "keyActualValue": "log_config.enable is set to false", + } +} diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json index a9432c792f8..8a52a6eb6ed 100644 --- a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "3f1222a9", "cloudProvider": "gcp", "cwe": "CWE-284", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego index 7ba18522e71..b4b25a906fe 100644 --- a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego @@ -1,51 +1,59 @@ -package Cx - -# REGLA 1: El bloque 'iap' está ausente en google_compute_backend_service. -CxPolicy[result] { - doc := input.document[i] - bs := doc.resource.google_compute_backend_service[name] - - not bs.iap - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_compute_backend_service.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'google_compute_backend_service.%s' should have an 'iap' block defined", [name]), - "keyActualValue": sprintf("'google_compute_backend_service.%s' is missing the 'iap' block", [name]), - } -} - -# REGLA 2: El bloque 'iap' existe pero falta 'oauth2_client_id'. -CxPolicy[result] { - doc := input.document[i] - bs := doc.resource.google_compute_backend_service[name] - - bs.iap - not bs.iap.oauth2_client_id - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_compute_backend_service.%s.iap", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'oauth2_client_id' should be defined within the 'iap' block", - "keyActualValue": "'oauth2_client_id' is missing", - } -} - -# REGLA 3: El bloque 'iap' existe pero falta 'oauth2_client_secret'. -CxPolicy[result] { - doc := input.document[i] - bs := doc.resource.google_compute_backend_service[name] - - bs.iap - not bs.iap.oauth2_client_secret - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_compute_backend_service.%s.iap", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'oauth2_client_secret' should be defined within the 'iap' block", - "keyActualValue": "'oauth2_client_secret' is missing", - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +# REGLA 1: El bloque 'iap' está ausente en google_compute_backend_service. +CxPolicy[result] { + doc := input.document[i] + bs := doc.resource.google_compute_backend_service[name] + + not bs.iap + + result := { + "documentId": doc.id, + "resourceType": "google_compute_backend_service", + "resourceName": tf_lib.get_resource_name(bs, name), + "searchKey": sprintf("google_compute_backend_service[%s]", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'google_compute_backend_service.%s' should have an 'iap' block defined", [name]), + "keyActualValue": sprintf("'google_compute_backend_service.%s' is missing the 'iap' block", [name]), + } +} + +# REGLA 2: El bloque 'iap' existe pero falta 'oauth2_client_id'. +CxPolicy[result] { + doc := input.document[i] + bs := doc.resource.google_compute_backend_service[name] + + bs.iap + not bs.iap.oauth2_client_id + + result := { + "documentId": doc.id, + "resourceType": "google_compute_backend_service", + "resourceName": tf_lib.get_resource_name(bs, name), + "searchKey": sprintf("google_compute_backend_service[%s].iap", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'oauth2_client_id' should be defined within the 'iap' block", + "keyActualValue": "'oauth2_client_id' is missing", + } +} + +# REGLA 3: El bloque 'iap' existe pero falta 'oauth2_client_secret'. +CxPolicy[result] { + doc := input.document[i] + bs := doc.resource.google_compute_backend_service[name] + + bs.iap + not bs.iap.oauth2_client_secret + + result := { + "documentId": doc.id, + "resourceType": "google_compute_backend_service", + "resourceName": tf_lib.get_resource_name(bs, name), + "searchKey": sprintf("google_compute_backend_service[%s].iap", [name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'oauth2_client_secret' should be defined within the 'iap' block", + "keyActualValue": "'oauth2_client_secret' is missing", + } +} diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json index ac5563b73c0..f22e4df4ca1 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json @@ -9,5 +9,5 @@ "descriptionID": "80d98d7b", "cloudProvider": "gcp", "cwe": "CWE-532", - "riskScore": 5.0 + "riskScore": "5.0" } \ No newline at end of file diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego index 080bfd7bc97..9a7d4410a0d 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego @@ -1,25 +1,29 @@ -package Cx - -ensure_array(x) = x { is_array(x) } -ensure_array(x) = [x] { is_object(x) } - -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_sql_database_instance[name] - - contains(resource.database_version, "POSTGRES") - - flags := ensure_array(resource.settings.database_flags) - flag := flags[j] - - flag.name == "log_error_verbosity" - lower(flag.value) == "verbose" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.google_sql_database_instance.%s.settings.database_flags", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'log_error_verbosity' should be set to 'default' or 'terse'", - "keyActualValue": sprintf("'log_error_verbosity' is set to '%s'", [flag.value]), - } -} \ No newline at end of file +package Cx + +import data.generic.terraform as tf_lib + +ensure_array(x) = x { is_array(x) } +ensure_array(x) = [x] { is_object(x) } + +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_sql_database_instance[name] + + contains(resource.database_version, "POSTGRES") + + flags := ensure_array(resource.settings.database_flags) + flag := flags[j] + + flag.name == "log_error_verbosity" + lower(flag.value) == "verbose" + + result := { + "documentId": doc.id, + "resourceType": "google_sql_database_instance", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_sql_database_instance[%s].settings.database_flags", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'log_error_verbosity' should be set to 'default' or 'terse'", + "keyActualValue": sprintf("'log_error_verbosity' is set to '%s'", [flag.value]), + } +} From 99caa64cf54cfbb9fa7d85da2172b305d60ff3a5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Mon, 23 Mar 2026 20:57:51 +0000 Subject: [PATCH 005/900] updated from spanish to english --- .../README.md | 92 ++++----- .../query.rego | 4 +- .../README.md | 110 +++++------ .../query.rego | 4 +- .../README.md | 74 +++---- .../query.rego | 2 +- .../README.md | 94 ++++----- .../query.rego | 4 +- .../README.md | 84 ++++---- .../query.rego | 2 +- .../azure_bastion_host_missing/README.md | 100 +++++----- .../azure_bastion_host_missing/query.rego | 2 +- .../README.md | 72 +++---- .../query.rego | 2 +- .../README.md | 104 +++++----- .../query.rego | 4 +- .../README.md | 136 ++++++------- .../query.rego | 4 +- .../azure_iot_hub_defender_disabled/README.md | 144 +++++++------- .../query.rego | 2 +- .../README.md | 128 ++++++------ .../query.rego | 2 +- .../README.md | 120 +++++------ .../query.rego | 2 +- .../README.md | 118 +++++------ .../query.rego | 2 +- .../README.md | 118 +++++------ .../query.rego | 2 +- .../README.md | 130 ++++++------ .../query.rego | 2 +- .../README.md | 134 ++++++------- .../query.rego | 2 +- .../README.md | 138 ++++++------- .../query.rego | 4 +- .../README.md | 122 ++++++------ .../query.rego | 2 +- .../README.md | 144 +++++++------- .../query.rego | 4 +- .../README.md | 158 +++++++-------- .../query.rego | 4 +- .../README.md | 112 +++++------ .../query.rego | 2 +- .../README.md | 110 +++++------ .../query.rego | 2 +- .../README.md | 144 +++++++------- .../query.rego | 4 +- .../README.md | 126 ++++++------ .../query.rego | 4 +- .../README.md | 152 +++++++------- .../query.rego | 6 +- .../README.md | 92 ++++----- .../query.rego | 6 +- .../README.md | 130 ++++++------ .../query.rego | 4 +- .../README.md | 124 ++++++------ .../query.rego | 4 +- .../README.md | 186 +++++++++--------- .../query.rego | 8 +- .../README.md | 104 +++++----- .../query.rego | 6 +- .../gcp_access_approval_disabled/README.md | 100 +++++----- .../gcp_access_approval_disabled/query.rego | 4 +- .../gcp_api_key_api_targets_missing/README.md | 114 +++++------ .../query.rego | 4 +- .../gcp_api_key_restrictions_manual/README.md | 108 +++++----- .../README.md | 114 +++++------ .../query.rego | 4 +- .../README.md | 98 ++++----- .../query.rego | 6 +- .../README.md | 102 +++++----- .../query.rego | 4 +- .../README.md | 92 ++++----- .../query.rego | 6 +- .../gcp/gcp_gke_manual_iam_check/README.md | 76 +++---- .../gcp/gcp_gke_manual_iam_check/query.rego | 4 +- .../README.md | 94 ++++----- .../query.rego | 8 +- .../gcp/gcp_gke_sandbox_disabled/README.md | 104 +++++----- .../gcp/gcp_gke_sandbox_disabled/query.rego | 8 +- .../README.md | 100 +++++----- .../query.rego | 6 +- .../gcp_gke_security_posture_manual/README.md | 90 ++++----- .../query.rego | 4 +- .../README.md | 108 +++++----- .../query.rego | 4 +- .../README.md | 94 ++++----- .../README.md | 106 +++++----- .../README.md | 80 ++++---- .../README.md | 102 +++++----- .../query.rego | 4 +- 90 files changed, 2725 insertions(+), 2725 deletions(-) diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/README.md b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/README.md index 151365fca5b..d8327339318 100644 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/README.md +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/README.md @@ -1,46 +1,46 @@ -# Regla KICS: App Service Application Insights Not Configured - -## Descripción General - -Esta regla verifica que los servicios de Azure App Service y Function Apps tengan configurada la integración con **Application Insights**. - -Application Insights es una característica de Azure Monitor que proporciona gestión del rendimiento de aplicaciones (APM) y seguimiento de errores en tiempo real. Para vincular un App Service con Application Insights en Terraform, se debe definir `APPLICATIONINSIGHTS_CONNECTION_STRING` (recomendado) o `APPINSIGHTS_INSTRUMENTATIONKEY` dentro del bloque `app_settings`. - -## Lógica de la Regla - -La política itera sobre los recursos `azurerm_linux_web_app`, `azurerm_windows_web_app`, `azurerm_linux_function_app` y `azurerm_windows_function_app`. -Verifica la configuración en dos niveles: -1. **Ausencia de app_settings:** Si el bloque no está definido. -2. **Configuración incompleta:** Si el bloque existe pero no contiene las claves de conexión. - -## Casos de Fallo Detectados - -### Caso 1: Falta Configuración en app_settings - -* **Descripción:** El recurso no tiene el bloque `app_settings` definido. -* **Ubicación de la Alerta:** Nivel de recurso principal. - -### Caso 2: Claves de App Insights ausentes - -* **Descripción:** El bloque `app_settings` existe pero no contiene `APPLICATIONINSIGHTS_CONNECTION_STRING` ni `APPINSIGHTS_INSTRUMENTATIONKEY`. -* **Ubicación de la Alerta:** Atributo `app_settings`. - -## Recurso Involucrado - -* `azurerm_linux_web_app` -* `azurerm_windows_web_app` -* `azurerm_linux_function_app` -* `azurerm_windows_function_app` - -## Solución - -Defina `APPLICATIONINSIGHTS_CONNECTION_STRING` dentro de los `app_settings`. - -```terraform -resource "azurerm_linux_web_app" "example" { - name = "example-app" - # ... - app_settings = { - "APPLICATIONINSIGHTS_CONNECTION_STRING" = azurerm_application_insights.example.connection_string - } -} \ No newline at end of file +# KICS Rule: App Service Application Insights Not Configured + +## General Description + +This rule verifies that Azure App Service and Function Apps have **Application Insights** integration configured. + +Application Insights is an Azure Monitor feature that provides application performance management (APM) and real-time error tracking. To link an App Service with Application Insights in Terraform, `APPLICATIONINSIGHTS_CONNECTION_STRING` (recommended) or `APPINSIGHTS_INSTRUMENTATIONKEY` must be defined within the `app_settings` block. + +## Rule Logic + +The policy iterates over `azurerm_linux_web_app`, `azurerm_windows_web_app`, `azurerm_linux_function_app`, and `azurerm_windows_function_app` resources. +It checks the configuration at two levels: +1. **Absence of app_settings:** If the block is not defined. +2. **Incomplete configuration:** If the block exists but does not contain the connection keys. + +## Detected Failure Cases + +### Case 1: Missing app_settings Configuration + +* **Description:** The resource does not have the `app_settings` block defined. +* **Alert Location:** Main resource level. + +### Case 2: App Insights Keys Missing + +* **Description:** The `app_settings` block exists but does not contain `APPLICATIONINSIGHTS_CONNECTION_STRING` or `APPINSIGHTS_INSTRUMENTATIONKEY`. +* **Alert Location:** `app_settings` attribute. + +## Involved Resource + +* `azurerm_linux_web_app` +* `azurerm_windows_web_app` +* `azurerm_linux_function_app` +* `azurerm_windows_function_app` + +## Solution + +Define `APPLICATIONINSIGHTS_CONNECTION_STRING` within `app_settings`. + +```terraform +resource "azurerm_linux_web_app" "example" { + name = "example-app" + # ... + app_settings = { + "APPLICATIONINSIGHTS_CONNECTION_STRING" = azurerm_application_insights.example.connection_string + } +} diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego index f20fb3ab448..8cbaef5d9e8 100644 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego @@ -9,7 +9,7 @@ targets := { "azurerm_windows_function_app" } -# REGLA 1: El bloque 'app_settings' no existe en absoluto. +# RULE 1: The 'app_settings' block does not exist at all. CxPolicy[result] { doc := input.document[i] resource_type := targets[t] @@ -28,7 +28,7 @@ CxPolicy[result] { } } -# REGLA 2: El bloque 'app_settings' existe pero no tiene ninguna clave de App Insights. +# RULE 2: The 'app_settings' block exists but does not have any App Insights key. CxPolicy[result] { doc := input.document[i] resource_type := targets[t] diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/README.md b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/README.md index 9ee37293f24..d3201cb2649 100644 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/README.md +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/README.md @@ -1,55 +1,55 @@ -# Regla KICS: App Service HTTP Logs Disabled - -## Descripción General - -Esta regla verifica que los servicios de Azure App Service (`azurerm_linux_web_app` y `azurerm_windows_web_app`) tengan habilitados los logs HTTP. - -Los logs de HTTP registran las solicitudes web que recibe la aplicación, incluyendo la URL solicitada, el agente de usuario, la dirección IP del cliente y el código de estado de la respuesta. Esta información es fundamental para la auditoría de seguridad, el cumplimiento normativo y la resolución de problemas de tráfico. - -## Lógica de la Regla - -La política itera sobre los recursos de App Service y verifica la configuración en dos pasos: -1. **Ausencia de Logs:** Verifica si el bloque `logs` existe. -2. **Ausencia de Logs HTTP:** Si el bloque `logs` existe, verifica que contenga el sub-bloque `http_logs`. - -Si el logging HTTP no está explícitamente habilitado, se genera una alerta. - -## Casos de Fallo Detectados - -### Caso 1: Configuración de Logs Ausente - -* **Descripción:** El recurso App Service se define sin especificar ninguna configuración de `logs`. -* **Ubicación de la Alerta:** Nivel de recurso principal. - -### Caso 2: Bloque http_logs Omitido - -* **Descripción:** Se define el bloque `logs` (por ejemplo, para logs de aplicación), pero se omiten los logs de tráfico HTTP. -* **Ubicación de la Alerta:** Bloque `logs`. - -## Recurso Involucrado - -* `azurerm_linux_web_app` -* `azurerm_windows_web_app` - -## Solución - -Añada el bloque `logs` y configure `http_logs` definiendo un sistema de archivos (`file_system`) o un almacenamiento de blobs (`azure_blob_storage`). - -```terraform -resource "azurerm_linux_web_app" "example_secure" { - name = "example-linux-web-app-secure" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - service_plan_id = azurerm_service_plan.example.id - - site_config {} - - logs { - http_logs { - file_system { - retention_in_days = 7 - retention_in_mb = 35 - } - } - } -} \ No newline at end of file +# KICS Rule: App Service HTTP Logs Disabled + +## General Description + +This rule verifies that Azure App Service resources (`azurerm_linux_web_app` and `azurerm_windows_web_app`) have HTTP logs enabled. + +HTTP logs record the web requests received by the application, including the requested URL, user agent, client IP address, and response status code. This information is essential for security auditing, regulatory compliance, and troubleshooting traffic issues. + +## Rule Logic + +The policy iterates over App Service resources and checks the configuration in two steps: +1. **Absence of Logs:** Checks whether the `logs` block exists. +2. **Absence of HTTP Logs:** If the `logs` block exists, checks that it contains the `http_logs` sub-block. + +If HTTP logging is not explicitly enabled, an alert is generated. + +## Detected Failure Cases + +### Case 1: Missing Logs Configuration + +* **Description:** The App Service resource is defined without specifying any `logs` configuration. +* **Alert Location:** Main resource level. + +### Case 2: http_logs Block Omitted + +* **Description:** The `logs` block is defined (e.g., for application logs), but HTTP traffic logs are omitted. +* **Alert Location:** `logs` block. + +## Involved Resource + +* `azurerm_linux_web_app` +* `azurerm_windows_web_app` + +## Solution + +Add the `logs` block and configure `http_logs` by defining a file system (`file_system`) or blob storage (`azure_blob_storage`). + +```terraform +resource "azurerm_linux_web_app" "example_secure" { + name = "example-linux-web-app-secure" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + service_plan_id = azurerm_service_plan.example.id + + site_config {} + + logs { + http_logs { + file_system { + retention_in_days = 7 + retention_in_mb = 35 + } + } + } +} diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego index 7b56ce92f11..9d0be296f83 100644 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego @@ -4,7 +4,7 @@ import data.generic.terraform as tf_lib targets := {"azurerm_linux_web_app", "azurerm_windows_web_app"} -# REGLA 1: El bloque 'logs' no existe en el App Service. +# RULE 1: The 'logs' block does not exist in the App Service. CxPolicy[result] { doc := input.document[i] resource_type := targets[t] @@ -23,7 +23,7 @@ CxPolicy[result] { } } -# REGLA 2: El bloque 'logs' existe pero no tiene 'http_logs' configurado. +# RULE 2: The 'logs' block exists but does not have 'http_logs' configured. CxPolicy[result] { doc := input.document[i] resource_type := targets[t] diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/README.md index deb4f3433de..2e8563a44a8 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/README.md +++ b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/README.md @@ -1,37 +1,37 @@ -# Regla KICS: Backup Vault CMK Encryption Disabled - -## Descripción General - -Esta regla verifica que los almacenes de copias de seguridad de Azure (**Backup Vaults** del servicio Data Protection) estén cifrados utilizando **Customer-Managed Keys (CMK)**. - -El uso de claves gestionadas por el cliente proporciona un control total sobre el ciclo de vida de las claves (creación, rotación y revocación) y es un requisito común en entornos con altas exigencias de seguridad y cumplimiento. En Terraform, esto se configura mediante un recurso separado (`azurerm_data_protection_backup_vault_customer_managed_key`) que vincula el Vault con la clave almacenada en un Key Vault. - -## Lógica de la Regla - -La política realiza un análisis de relaciones entre recursos: -1. Identifica todos los recursos `azurerm_data_protection_backup_vault`. -2. Busca si existe un recurso `azurerm_data_protection_backup_vault_customer_managed_key` cuya propiedad `data_protection_backup_vault_id` apunte al Vault analizado. -3. Verifica que dicho recurso de asociación tenga definido el atributo `key_vault_key_id`. -4. Si no existe esta vinculación, se genera una alerta indicando que el Vault usa claves gestionadas por la plataforma (configuración por defecto). - -## Casos de Fallo Detectados - -### Caso 1: Backup Vault sin CMK - -* **Descripción:** Se define el Backup Vault pero no se encuentra el recurso de asociación de la clave de cifrado gestionada por el cliente. -* **Ubicación de la Alerta:** Sobre el recurso `azurerm_data_protection_backup_vault`. - -## Recurso Involucrado - -* `azurerm_data_protection_backup_vault` -* `azurerm_data_protection_backup_vault_customer_managed_key` - -## Solución - -Define el recurso de asociación `azurerm_data_protection_backup_vault_customer_managed_key` y vincúlalo al Vault y a la Key correspondiente. - -```terraform -resource "azurerm_data_protection_backup_vault_customer_managed_key" "example" { - data_protection_backup_vault_id = azurerm_data_protection_backup_vault.example.id - key_vault_key_id = azurerm_key_vault_key.example.id -} \ No newline at end of file +# KICS Rule: Backup Vault CMK Encryption Disabled + +## General Description + +This rule verifies that Azure backup vaults (**Backup Vaults** from the Data Protection service) are encrypted using **Customer-Managed Keys (CMK)**. + +Using customer-managed keys provides full control over the key lifecycle (creation, rotation, and revocation) and is a common requirement in environments with high security and compliance demands. In Terraform, this is configured through a separate resource (`azurerm_data_protection_backup_vault_customer_managed_key`) that links the Vault to the key stored in a Key Vault. + +## Rule Logic + +The policy performs a relationship analysis between resources: +1. Identifies all `azurerm_data_protection_backup_vault` resources. +2. Searches for an `azurerm_data_protection_backup_vault_customer_managed_key` resource whose `data_protection_backup_vault_id` property points to the analyzed Vault. +3. Verifies that this association resource has the `key_vault_key_id` attribute defined. +4. If this linkage does not exist, an alert is generated indicating that the Vault uses platform-managed keys (default configuration). + +## Detected Failure Cases + +### Case 1: Backup Vault Without CMK + +* **Description:** The Backup Vault is defined but the customer-managed encryption key association resource is not found. +* **Alert Location:** On the `azurerm_data_protection_backup_vault` resource. + +## Involved Resource + +* `azurerm_data_protection_backup_vault` +* `azurerm_data_protection_backup_vault_customer_managed_key` + +## Solution + +Define the `azurerm_data_protection_backup_vault_customer_managed_key` association resource and link it to the Vault and the corresponding Key. + +```terraform +resource "azurerm_data_protection_backup_vault_customer_managed_key" "example" { + data_protection_backup_vault_id = azurerm_data_protection_backup_vault.example.id + key_vault_key_id = azurerm_key_vault_key.example.id +} diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego index 1e78a4e383c..5be62a40e54 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego @@ -8,7 +8,7 @@ has_cmk_configured(doc, vault_id) { cmk.key_vault_key_id } -# REGLA 1: El Backup Vault no tiene cifrado CMK configurado a través del recurso de asociación. +# RULE 1: The Backup Vault does not have CMK encryption configured through the association resource. CxPolicy[result] { doc := input.document[i] vault := doc.resource.azurerm_data_protection_backup_vault[name] diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/README.md b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/README.md index 14f5f15e08b..bbf12d0bf78 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/README.md +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/README.md @@ -1,47 +1,47 @@ -# Regla KICS: Backup Vault Cross Region Restore Disabled - -## Descripción General - -Esta regla verifica que la funcionalidad de **Restauración entre Regiones** (`cross_region_restore_enabled`) esté habilitada en los recursos `azurerm_data_protection_backup_vault`. - -Cross Region Restore (CRR) permite restaurar los datos de copia de seguridad en una región secundaria de Azure emparejada (Azure Paired Region). Esto es fundamental para garantizar la continuidad del negocio y la recuperación de datos en caso de que la región principal sufra una interrupción total o un desastre geográfico. - -**Nota:** Para utilizar CRR de manera efectiva, el almacén requiere que la redundancia esté configurada como `GeoRedundant`. - -## Lógica de la Regla - -La política evalúa el recurso `azurerm_data_protection_backup_vault` bajo dos escenarios: -1. **Atributo Ausente:** Si no se define explícitamente `cross_region_restore_enabled`, se genera una alerta sobre el recurso (ya que el valor por defecto en la plataforma suele ser false). -2. **Deshabilitado Explícitamente:** Si el atributo se establece como `false`, la alerta apunta directamente a la línea de la configuración incorrecta. - -## Casos de Fallo Detectados - ---- - -### Caso 1: Configuración Ausente -* **Descripción:** Se define el Backup Vault sin especificar la política de restauración entre regiones, dejando los datos vulnerables a fallos regionales. -* **Ubicación de la Alerta:** Nivel de recurso `azurerm_data_protection_backup_vault`. - -### Caso 2: CRR Deshabilitado -* **Descripción:** El atributo `cross_region_restore_enabled` está configurado explícitamente como `false`. -* **Ubicación de la Alerta:** Línea `cross_region_restore_enabled`. - -## Recurso Involucrado - -* `azurerm_data_protection_backup_vault` - -## Solución - -Establezca el atributo `cross_region_restore_enabled` en `true`. Es altamente recomendable verificar que el tipo de redundancia (`redundancy`) esté configurado como `GeoRedundant`. - -```terraform -resource "azurerm_data_protection_backup_vault" "example_secure" { - name = "vault-secure" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - datastore_type = "VaultStore" - redundancy = "GeoRedundant" - - # Solución técnica - cross_region_restore_enabled = true -} \ No newline at end of file +# KICS Rule: Backup Vault Cross Region Restore Disabled + +## General Description + +This rule verifies that the **Cross Region Restore** functionality (`cross_region_restore_enabled`) is enabled on `azurerm_data_protection_backup_vault` resources. + +Cross Region Restore (CRR) allows backup data to be restored in a secondary paired Azure region (Azure Paired Region). This is essential to ensure business continuity and data recovery in the event that the primary region suffers a total outage or geographic disaster. + +**Note:** To use CRR effectively, the vault requires redundancy to be configured as `GeoRedundant`. + +## Rule Logic + +The policy evaluates the `azurerm_data_protection_backup_vault` resource under two scenarios: +1. **Missing Attribute:** If `cross_region_restore_enabled` is not explicitly defined, an alert is generated on the resource (since the default value on the platform is usually false). +2. **Explicitly Disabled:** If the attribute is set to `false`, the alert points directly to the line of the incorrect configuration. + +## Detected Failure Cases + +--- + +### Case 1: Missing Configuration +* **Description:** The Backup Vault is defined without specifying the cross-region restore policy, leaving data vulnerable to regional failures. +* **Alert Location:** Resource level `azurerm_data_protection_backup_vault`. + +### Case 2: CRR Disabled +* **Description:** The `cross_region_restore_enabled` attribute is explicitly configured as `false`. +* **Alert Location:** Line `cross_region_restore_enabled`. + +## Involved Resource + +* `azurerm_data_protection_backup_vault` + +## Solution + +Set the `cross_region_restore_enabled` attribute to `true`. It is highly recommended to verify that the redundancy type (`redundancy`) is configured as `GeoRedundant`. + +```terraform +resource "azurerm_data_protection_backup_vault" "example_secure" { + name = "vault-secure" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + datastore_type = "VaultStore" + redundancy = "GeoRedundant" + + # Technical solution + cross_region_restore_enabled = true +} diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego index c119b997648..9b22682a4be 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: Configuración Ausente. +# RULE 1: Missing Configuration. CxPolicy[result] { doc := input.document[i] vault := doc.resource.azurerm_data_protection_backup_vault[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: Configuración Incorrecta (Deshabilitado explícitamente). +# RULE 2: Incorrect Configuration (Explicitly disabled). CxPolicy[result] { doc := input.document[i] vault := doc.resource.azurerm_data_protection_backup_vault[name] diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/README.md index 9ca0aa51be4..f1030a1f25a 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/README.md +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/README.md @@ -1,42 +1,42 @@ -# Regla KICS: Backup Vault Infrastructure Encryption Disabled - -## Descripción General - -Esta regla verifica la preparación para el cifrado avanzado en los almacenes de respaldo de Azure (**Data Protection Backup Vaults**). - -Para que un Backup Vault pueda soportar capas de cifrado adicionales o gestionadas por el cliente (CMK), es obligatorio que el recurso tenga una identidad asignada (`identity`). Sin una identidad, el almacén solo puede utilizar el cifrado predeterminado de la plataforma. - -## Lógica de la Regla - -La política audita el recurso `azurerm_data_protection_backup_vault`: -1. Verifica la existencia del bloque `identity`. -2. Si el bloque está ausente, se considera que el recurso no está preparado para configuraciones de cifrado de infraestructura o gestionado por el cliente. - -## Casos de Fallo Detectados - -### Caso 1: Identidad no configurada - -* **Descripción:** El Backup Vault no tiene una identidad (SystemAssigned o UserAssigned), lo que impide la vinculación con claves de cifrado externas. -* **Ubicación de la Alerta:** Nivel de recurso `azurerm_data_protection_backup_vault`. - -## Recurso Involucrado - -* `azurerm_data_protection_backup_vault` - -## Solución - -Añada un bloque `identity` al recurso. - -```terraform -resource "azurerm_data_protection_backup_vault" "example" { - name = "vault-secure" - resource_group_name = "rg-example" - location = "West Europe" - datastore_type = "VaultStore" - redundancy = "LocallyRedundant" - - # Solución técnica para habilitar capacidades de cifrado - identity { - type = "SystemAssigned" - } -} \ No newline at end of file +# KICS Rule: Backup Vault Infrastructure Encryption Disabled + +## General Description + +This rule verifies readiness for advanced encryption in Azure backup vaults (**Data Protection Backup Vaults**). + +For a Backup Vault to support additional or customer-managed (CMK) encryption layers, the resource must have an assigned identity (`identity`). Without an identity, the vault can only use the platform's default encryption. + +## Rule Logic + +The policy audits the `azurerm_data_protection_backup_vault` resource: +1. Verifies the existence of the `identity` block. +2. If the block is absent, the resource is considered not ready for infrastructure or customer-managed encryption configurations. + +## Detected Failure Cases + +### Case 1: Identity Not Configured + +* **Description:** The Backup Vault does not have an identity (SystemAssigned or UserAssigned), which prevents linking to external encryption keys. +* **Alert Location:** Resource level `azurerm_data_protection_backup_vault`. + +## Involved Resource + +* `azurerm_data_protection_backup_vault` + +## Solution + +Add an `identity` block to the resource. + +```terraform +resource "azurerm_data_protection_backup_vault" "example" { + name = "vault-secure" + resource_group_name = "rg-example" + location = "West Europe" + datastore_type = "VaultStore" + redundancy = "LocallyRedundant" + + # Technical solution to enable encryption capabilities + identity { + type = "SystemAssigned" + } +} diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego index f76ea1d04fe..26e9ed31482 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: Falta el bloque 'identity', necesario para gestionar cifrado avanzado. +# RULE 1: The 'identity' block is missing, which is required to manage advanced encryption. CxPolicy[result] { doc := input.document[i] vault := doc.resource.azurerm_data_protection_backup_vault[name] diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/README.md b/assets/queries/terraform/azure/azure_bastion_host_missing/README.md index 63ef51ce4f3..6b3a63a070f 100644 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/README.md +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/README.md @@ -1,50 +1,50 @@ -# Regla KICS: Azure Bastion Host Missing - -## Descripción General - -Esta regla verifica que, si se están desplegando redes virtuales (`azurerm_virtual_network`), exista al menos un recurso **Azure Bastion Host** (`azurerm_bastion_host`) definido en la configuración. - -Azure Bastion es un servicio PaaS que se aprovisiona dentro de una red virtual. Proporciona conectividad RDP y SSH segura directamente desde el portal de Azure a través de SSL. Esto elimina la necesidad de exponer puertos administrativos (22, 3389) a Internet o gestionar complejas VPNs y Jumpboxes para tareas de mantenimiento, reduciendo drásticamente la superficie de ataque. - -## Lógica de la Regla - -La política realiza un análisis de presencia de recursos a nivel de documento: -1. Verifica si existe algún recurso `azurerm_virtual_network`. -2. Si existen redes, busca si hay algún recurso `azurerm_bastion_host` definido en el mismo archivo/contexto. -3. Si existen redes pero no se encuentra ningún Bastion Host, se genera una alerta sobre la red virtual. - -## Casos de Fallo Detectados - -### Caso 1: VNet sin Bastion Host - -* **Descripción:** Se define infraestructura de red, pero no se incluye el servicio de Bastion, lo que sugiere que el acceso administrativo podría estar realizándose de forma insegura mediante IPs públicas directas o puertos abiertos en los grupos de seguridad (NSG). -* **Ubicación de la Alerta:** Sobre el recurso `azurerm_virtual_network`. - -## Recurso Involucrado - -* `azurerm_virtual_network` -* `azurerm_bastion_host` - -## Solución - -Para solucionar el problema, define un recurso `azurerm_bastion_host` y asegúrate de crear la subred obligatoria llamada `AzureBastionSubnet`. - -```terraform -resource "azurerm_subnet" "example_bastion" { - name = "AzureBastionSubnet" - resource_group_name = azurerm_resource_group.example.name - virtual_network_name = azurerm_virtual_network.example.name - address_prefixes = ["10.0.1.0/24"] -} - -resource "azurerm_bastion_host" "example" { - name = "production-bastion" - location = azurerm_resource_group.example.location - resource_group_name = azurerm_resource_group.example.name - - ip_configuration { - name = "configuration" - subnet_id = azurerm_subnet.example_bastion.id - public_ip_address_id = azurerm_public_ip.example.id - } -} \ No newline at end of file +# KICS Rule: Azure Bastion Host Missing + +## General Description + +This rule verifies that, if virtual networks (`azurerm_virtual_network`) are being deployed, at least one **Azure Bastion Host** resource (`azurerm_bastion_host`) is defined in the configuration. + +Azure Bastion is a PaaS service provisioned within a virtual network. It provides secure RDP and SSH connectivity directly from the Azure portal over SSL. This eliminates the need to expose administrative ports (22, 3389) to the Internet or manage complex VPNs and Jumpboxes for maintenance tasks, drastically reducing the attack surface. + +## Rule Logic + +The policy performs a resource presence analysis at the document level: +1. Checks whether any `azurerm_virtual_network` resource exists. +2. If networks exist, looks for any `azurerm_bastion_host` resource defined in the same file/context. +3. If networks exist but no Bastion Host is found, an alert is generated on the virtual network. + +## Detected Failure Cases + +### Case 1: VNet without Bastion Host + +* **Description:** Network infrastructure is defined, but the Bastion service is not included, suggesting that administrative access may be performed insecurely via direct public IPs or open ports in security groups (NSG). +* **Alert Location:** On the `azurerm_virtual_network` resource. + +## Involved Resource + +* `azurerm_virtual_network` +* `azurerm_bastion_host` + +## Solution + +To fix the issue, define an `azurerm_bastion_host` resource and make sure to create the mandatory subnet named `AzureBastionSubnet`. + +```terraform +resource "azurerm_subnet" "example_bastion" { + name = "AzureBastionSubnet" + resource_group_name = azurerm_resource_group.example.name + virtual_network_name = azurerm_virtual_network.example.name + address_prefixes = ["10.0.1.0/24"] +} + +resource "azurerm_bastion_host" "example" { + name = "production-bastion" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + ip_configuration { + name = "configuration" + subnet_id = azurerm_subnet.example_bastion.id + public_ip_address_id = azurerm_public_ip.example.id + } +} diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego b/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego index b777996ee5d..6effebc737b 100644 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: Existe una VNet, pero no existe ningún recurso azurerm_bastion_host en el documento. +# RULE 1: A VNet exists, but no azurerm_bastion_host resource exists in the document. CxPolicy[result] { doc := input.document[i] diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/README.md b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/README.md index c4411fe5e3f..b724a63ae19 100644 --- a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/README.md +++ b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/README.md @@ -1,36 +1,36 @@ -# Regla KICS: Microsoft Defender EASM Enabled (Manual) - -## Descripción General - -Esta regla funciona como un **recordatorio de cumplimiento manual**. Su objetivo es asegurar que se haya habilitado **Microsoft Defender External Attack Surface Monitoring (EASM)** para monitorear la exposición de los activos de Azure a Internet. - -EASM realiza un descubrimiento continuo de tus activos digitales (direcciones IP, dominios, certificados SSL, etc.) para identificar vulnerabilidades y riesgos en la "sombra" (Shadow IT). Dado que el proveedor actual de Terraform para Azure no cuenta con recursos nativos para gestionar este servicio, la verificación debe realizarse directamente en la plataforma. - -## Lógica de la Regla - -Debido a las limitaciones del análisis estático para este servicio específico: -1. La regla identifica la presencia de recursos `azurerm_resource_group`. -2. Genera una alerta de severidad **INFO** por cada grupo detectado. -3. Actúa como un check-list para que el equipo de seguridad valide el estado del servicio en el Portal de Azure. - -## Casos de Fallo Detectados - -### Caso 1: Verificación Manual Requerida - -* **Descripción:** Se ha detectado infraestructura desplegada, pero el estado de protección de EASM no es visible para KICS. -* **Ubicación de la Alerta:** Sobre el recurso `azurerm_resource_group`. - -## Recurso Involucrado - -* `azurerm_resource_group` - -## Solución - -Esta alerta no se resuelve mediante cambios en el código HCL estándar. - -**Pasos de remediación manual:** -1. Acceda al [Portal de Azure](https://portal.azure.com). -2. En el buscador superior, escriba **"Microsoft Defender EASM"**. -3. Verifique si existe un recurso EASM configurado y realizando escaneos activos. -4. Si no existe, considere su creación para mejorar la postura de seguridad externa. -5. Documente la verificación para cerrar el hallazgo en el reporte de KICS. \ No newline at end of file +# KICS Rule: Microsoft Defender EASM Enabled (Manual) + +## General Description + +This rule acts as a **manual compliance reminder**. Its objective is to ensure that **Microsoft Defender External Attack Surface Monitoring (EASM)** has been enabled to monitor the exposure of Azure assets to the Internet. + +EASM continuously discovers your digital assets (IP addresses, domains, SSL certificates, etc.) to identify vulnerabilities and risks in the "shadow" (Shadow IT). Since the current Terraform provider for Azure does not have native resources to manage this service, verification must be performed directly on the platform. + +## Rule Logic + +Due to the limitations of static analysis for this specific service: +1. The rule identifies the presence of `azurerm_resource_group` resources. +2. It generates an **INFO** severity alert for each detected group. +3. It acts as a checklist for the security team to validate the service status in the Azure Portal. + +## Detected Failure Cases + +### Case 1: Manual Verification Required + +* **Description:** Deployed infrastructure has been detected, but the EASM protection status is not visible to KICS. +* **Alert Location:** On the `azurerm_resource_group` resource. + +## Involved Resource + +* `azurerm_resource_group` + +## Solution + +This alert is not resolved through changes in standard HCL code. + +**Manual remediation steps:** +1. Access the [Azure Portal](https://portal.azure.com). +2. In the top search bar, type **"Microsoft Defender EASM"**. +3. Verify whether an EASM resource is configured and performing active scans. +4. If it does not exist, consider creating it to improve the external security posture. +5. Document the verification to close the finding in the KICS report. diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego index e7bfbf42b0e..15b9a92a906 100644 --- a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego +++ b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: Genera un aviso manual por cada Resource Group encontrado. +# RULE 1: Generates a manual notice for each Resource Group found. CxPolicy[result] { doc := input.document[i] rg := doc.resource.azurerm_resource_group[name] diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/README.md b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/README.md index fc1bb17ee44..8eb70809996 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/README.md +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/README.md @@ -1,52 +1,52 @@ -# Regla KICS: Elastic SAN Public Network Access Enabled - -## Descripción General - -Esta regla de KICS verifica que los grupos de volúmenes de Azure Elastic SAN (`azurerm_elastic_san_volume_group`) tengan restringido el acceso desde redes públicas. - -En la arquitectura de Azure Elastic SAN, la seguridad y el aislamiento de red no se gestionan en el recurso raíz de la SAN, sino a nivel de **Volume Group**. Para garantizar que los volúmenes de datos no sean accesibles desde Internet, es imprescindible definir el bloque `network_rule`. La sola presencia de este bloque activa una política de denegación implícita para cualquier tráfico que no provenga de las subredes autorizadas, asegurando que la infraestructura solo sea accesible a través de la red privada. - -## Lógica de la Regla - -La política audita el recurso `azurerm_elastic_san_volume_group` analizando la siguiente condición: -1. **Existencia del Bloque de Red:** Se verifica la presencia del bloque `network_rule`. Si este bloque no está definido, el grupo de volúmenes carece de restricciones perimetrales, permitiendo potencialmente el acceso público. - -## Caso de Fallo Detectado - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso Único: Configuración de Red Ausente - -* **Descripción:** El grupo de volúmenes se define sin el bloque `network_rule`, lo que significa que no se están aplicando reglas de filtrado de IP o de red virtual para proteger los datos. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_elastic_san_volume_group" "example_insecure" { - name = "insecure-vg" - elastic_san_id = azurerm_elastic_san.example.id - - # El recurso carece del bloque network_rule, - # quedando expuesto a redes públicas. - } - ``` -* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_elastic_san_volume_group`. - -## Recurso Involucrado - -* `azurerm_elastic_san_volume_group` - -## Solución - -Para solucionar este riesgo de seguridad, defina el bloque `network_rule` vinculándolo a una subred autorizada mediante el atributo `subnet_id`. - -```terraform -resource "azurerm_elastic_san_volume_group" "secure_vg" { - name = "secure-volume-group" - elastic_san_id = azurerm_elastic_san.example.id - - # SOLUCIÓN: Definir reglas de red para denegar el acceso público - network_rule { - subnet_id = azurerm_subnet.example.id - } -} \ No newline at end of file +# KICS Rule: Elastic SAN Public Network Access Enabled + +## General Description + +This KICS rule verifies that Azure Elastic SAN volume groups (`azurerm_elastic_san_volume_group`) have public network access restricted. + +In the Azure Elastic SAN architecture, network security and isolation are not managed at the root SAN resource level, but at the **Volume Group** level. To ensure that data volumes are not accessible from the Internet, it is essential to define the `network_rule` block. The mere presence of this block activates an implicit deny policy for any traffic that does not originate from authorized subnets, ensuring that the infrastructure is only accessible through the private network. + +## Rule Logic + +The policy audits the `azurerm_elastic_san_volume_group` resource by analyzing the following condition: +1. **Network Block Existence:** The presence of the `network_rule` block is verified. If this block is not defined, the volume group lacks perimeter restrictions, potentially allowing public access. + +## Detected Failure Case + +The following describes the scenario this policy will detect. + +--- + +### Single Case: Missing Network Configuration + +* **Description:** The volume group is defined without the `network_rule` block, meaning no IP filtering or virtual network rules are being applied to protect the data. +* **Example of Problematic Terraform Code:** + ```terraform + resource "azurerm_elastic_san_volume_group" "example_insecure" { + name = "insecure-vg" + elastic_san_id = azurerm_elastic_san.example.id + + # The resource lacks the network_rule block, + # leaving it exposed to public networks. + } + ``` +* **Alert Location:** On the root `azurerm_elastic_san_volume_group` resource. + +## Involved Resource + +* `azurerm_elastic_san_volume_group` + +## Solution + +To fix this security risk, define the `network_rule` block linking it to an authorized subnet via the `subnet_id` attribute. + +```terraform +resource "azurerm_elastic_san_volume_group" "secure_vg" { + name = "secure-volume-group" + elastic_san_id = azurerm_elastic_san.example.id + + # SOLUTION: Define network rules to deny public access + network_rule { + subnet_id = azurerm_subnet.example.id + } +} diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego index 5cda347b958..61bbfc77306 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego @@ -2,8 +2,8 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: El bloque 'network_rule' no está definido. -# En azurerm_elastic_san_volume_group, la ausencia del bloque permite el acceso público. +# RULE 1: The 'network_rule' block is not defined. +# In azurerm_elastic_san_volume_group, the absence of the block allows public access. CxPolicy[result] { doc := input.document[i] vg := doc.resource.azurerm_elastic_san_volume_group[name] diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/README.md index fc8dfbdb8da..d26f9860843 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/README.md +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/README.md @@ -1,68 +1,68 @@ -# Regla KICS: Elastic SAN Volume Group CMK Encryption Disabled - -## Descripción General - -Esta regla de KICS verifica que los grupos de volúmenes de Azure Elastic SAN (`azurerm_elastic_san_volume_group`) estén configurados para utilizar claves gestionadas por el cliente (Customer-Managed Keys - CMK) para el cifrado de datos en reposo. - -El uso de CMK sobre las claves gestionadas por la plataforma por defecto es una práctica de seguridad crítica. Proporciona a las organizaciones un control total sobre el ciclo de vida de las claves criptográficas, incluyendo políticas de acceso, rotación y revocación. Esto es esencial para cumplir con requisitos regulatorios y garantizar que el acceso a los datos almacenados en la SAN esté protegido por claves bajo el control directo del cliente. - -## Lógica de la Regla - -La política analiza el recurso `azurerm_elastic_san_volume_group` validando dos pilares fundamentales: -1. **Configuración del Tipo:** El atributo `encryption_type` debe estar establecido inequívocamente como `EncryptionAtRestWithCustomerManagedKey`. -2. **Infraestructura de Soporte:** Si se selecciona CMK, el recurso debe incluir obligatoriamente los bloques `encryption` (que vincula la clave) e `identity` (que permite el acceso a la misma). - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- -### Caso 1: Cifrado CMK no Configurado (Uso de Claves de Plataforma) - -* **Descripción:** El recurso carece del atributo de cifrado CMK o utiliza el valor por defecto gestionado por la plataforma. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_elastic_san_volume_group" "fail_platform" { - name = "example-vg" - elastic_san_id = azurerm_elastic_san.example.id - } - ``` -* **Ubicación de la Alerta:** Recurso raíz `azurerm_elastic_san_volume_group`. - ---- -### Caso 2: CMK Seleccionado con Bloques Técnicos Ausentes - -* **Descripción:** Se ha activado el tipo de cifrado CMK, pero falta uno o ambos bloques (`encryption` / `identity`) necesarios para que el cifrado sea operativo. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_elastic_san_volume_group" "fail_missing_blocks" { - encryption_type = "EncryptionAtRestWithCustomerManagedKey" - # Falta bloque encryption o bloque identity - } - ``` -* **Ubicación de la Alerta:** Recurso raíz `azurerm_elastic_san_volume_group`. - -## Recurso Involucrado - -* `azurerm_elastic_san_volume_group` - -## Solución - -Para solucionar el problema, asegúrese de declarar el tipo de cifrado CMK e incluir los bloques técnicos requeridos con sus parámetros obligatorios. - -```terraform -resource "azurerm_elastic_san_volume_group" "secure_vg" { - name = "secure-volume-group" - elastic_san_id = azurerm_elastic_san.example.id - - encryption_type = "EncryptionAtRestWithCustomerManagedKey" - - encryption { - key_vault_key_id = azurerm_key_vault_key.example.id - } - - identity { - type = "UserAssigned" - identity_ids = [azurerm_user_assigned_identity.example.id] - } -} \ No newline at end of file +# KICS Rule: Elastic SAN Volume Group CMK Encryption Disabled + +## General Description + +This KICS rule verifies that Azure Elastic SAN volume groups (`azurerm_elastic_san_volume_group`) are configured to use Customer-Managed Keys (CMK) for data encryption at rest. + +Using CMK over default platform-managed keys is a critical security practice. It provides organizations with full control over the lifecycle of cryptographic keys, including access policies, rotation, and revocation. This is essential for meeting regulatory requirements and ensuring that data stored in the SAN is protected by keys under the direct control of the customer. + +## Rule Logic + +The policy analyzes the `azurerm_elastic_san_volume_group` resource by validating two fundamental pillars: +1. **Type Configuration:** The `encryption_type` attribute must be unambiguously set to `EncryptionAtRestWithCustomerManagedKey`. +2. **Supporting Infrastructure:** If CMK is selected, the resource must mandatorily include both the `encryption` block (which links the key) and the `identity` block (which grants access to it). + +## Detected Failure Cases + +The following describes the scenarios this policy will detect. + +--- +### Case 1: CMK Encryption Not Configured (Platform Key Usage) + +* **Description:** The resource lacks the CMK encryption attribute or uses the default platform-managed value. +* **Example of Problematic Terraform Code:** + ```terraform + resource "azurerm_elastic_san_volume_group" "fail_platform" { + name = "example-vg" + elastic_san_id = azurerm_elastic_san.example.id + } + ``` +* **Alert Location:** Root `azurerm_elastic_san_volume_group` resource. + +--- +### Case 2: CMK Selected with Missing Technical Blocks + +* **Description:** The CMK encryption type has been activated, but one or both required blocks (`encryption` / `identity`) needed for the encryption to be operational are missing. +* **Example of Problematic Terraform Code:** + ```terraform + resource "azurerm_elastic_san_volume_group" "fail_missing_blocks" { + encryption_type = "EncryptionAtRestWithCustomerManagedKey" + # Missing encryption block or identity block + } + ``` +* **Alert Location:** Root `azurerm_elastic_san_volume_group` resource. + +## Involved Resource + +* `azurerm_elastic_san_volume_group` + +## Solution + +To fix the issue, make sure to declare the CMK encryption type and include the required technical blocks with their mandatory parameters. + +```terraform +resource "azurerm_elastic_san_volume_group" "secure_vg" { + name = "secure-volume-group" + elastic_san_id = azurerm_elastic_san.example.id + + encryption_type = "EncryptionAtRestWithCustomerManagedKey" + + encryption { + key_vault_key_id = azurerm_key_vault_key.example.id + } + + identity { + type = "UserAssigned" + identity_ids = [azurerm_user_assigned_identity.example.id] + } +} diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego index e1d3f3a9fa8..b83ba1e8b05 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: El tipo de cifrado no es CMK o no está definido. +# RULE 1: The encryption type is not CMK or is not defined. CxPolicy[result] { doc := input.document[i] vg := doc.resource.azurerm_elastic_san_volume_group[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: Si el tipo es CMK, debe existir tanto el bloque 'encryption' como el bloque 'identity'. +# RULE 2: If the type is CMK, both the 'encryption' block and the 'identity' block must exist. CxPolicy[result] { doc := input.document[i] vg := doc.resource.azurerm_elastic_san_volume_group[name] diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/README.md b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/README.md index c40af7851dc..5078491f285 100644 --- a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/README.md +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/README.md @@ -1,72 +1,72 @@ -# Regla KICS: Azure IoT Hub Defender Disabled - -## Descripción General - -Esta regla de KICS verifica que los recursos **Azure IoT Hub** (`azurerm_iothub`) estén protegidos por **Microsoft Defender for IoT**. - -Microsoft Defender for IoT proporciona una capa esencial de seguridad para entornos de Internet de las cosas, ofreciendo detección de amenazas en tiempo real y gestión de la postura de seguridad. La falta de esta protección deja a los dispositivos IoT y a la infraestructura central del Hub vulnerables ante ataques dirigidos, movimientos laterales y exfiltración de datos. En Terraform, esta protección se habilita vinculando el IoT Hub con un recurso del tipo `azurerm_iot_security_solution`. - -## Lógica de la Regla - -La política analiza la configuración de Terraform realizando los siguientes pasos: -1. **Identificación de Hubs:** Selecciona todos los recursos de tipo `azurerm_iothub`. -2. **Verificación de Soluciones:** Busca recursos `azurerm_iot_security_solution` en el documento. -3. **Validación de Vinculación:** Comprueba si el identificador del Hub está presente en la lista `iothub_ids` de alguna solución de seguridad definida, contemplando formatos directos o interpolados. -4. **Generación de Alerta:** Si un Hub no está referenciado en ninguna solución, se genera un hallazgo de seguridad. - -## Caso de Fallo Detectado - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso Único: IoT Hub sin Defender asociado - -* **Descripción:** Se define un recurso `azurerm_iothub` pero no se encuentra ningún recurso `azurerm_iot_security_solution` que lo incluya en su lista de IDs protegidos. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_iothub" "fail_hub" { - name = "insecure-iothub" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - - sku { - name = "S1" - capacity = "1" - } - } - - # No existe azurerm_iot_security_solution que referencie a fail_hub - ``` -* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_iothub`. - -## Recurso Involucrado - -* `azurerm_iothub` -* `azurerm_iot_security_solution` - -## Solución - -Para solucionar este riesgo, asegúrese de definir un recurso `azurerm_iot_security_solution` e incluir el ID del IoT Hub en el atributo `iothub_ids`. - -```terraform -resource "azurerm_iothub" "example" { - name = "secure-iothub" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - - sku { - name = "S1" - capacity = "1" - } -} - -# SOLUCIÓN: Definir la solución de seguridad y vincular el Hub -resource "azurerm_iot_security_solution" "example" { - name = "iot-security-solution" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - display_name = "Iot Security Solution" - - iothub_ids = [azurerm_iothub.example.id] -} \ No newline at end of file +# KICS Rule: Azure IoT Hub Defender Disabled + +## General Description + +This KICS rule verifies that **Azure IoT Hub** resources (`azurerm_iothub`) are protected by **Microsoft Defender for IoT**. + +Microsoft Defender for IoT provides an essential layer of security for Internet of Things environments, offering real-time threat detection and security posture management. The lack of this protection leaves IoT devices and the Hub's central infrastructure vulnerable to targeted attacks, lateral movement, and data exfiltration. In Terraform, this protection is enabled by linking the IoT Hub with a resource of type `azurerm_iot_security_solution`. + +## Rule Logic + +The policy analyzes the Terraform configuration by performing the following steps: +1. **Hub Identification:** Selects all resources of type `azurerm_iothub`. +2. **Solution Verification:** Looks for `azurerm_iot_security_solution` resources in the document. +3. **Link Validation:** Checks whether the Hub's identifier is present in the `iothub_ids` list of any defined security solution, considering direct or interpolated formats. +4. **Alert Generation:** If a Hub is not referenced in any solution, a security finding is generated. + +## Detected Failure Case + +The following describes the scenario this policy will detect. + +--- + +### Single Case: IoT Hub without Associated Defender + +* **Description:** An `azurerm_iothub` resource is defined but no `azurerm_iot_security_solution` resource is found that includes it in its list of protected IDs. +* **Example of Problematic Terraform Code:** + ```terraform + resource "azurerm_iothub" "fail_hub" { + name = "insecure-iothub" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + + sku { + name = "S1" + capacity = "1" + } + } + + # No azurerm_iot_security_solution exists that references fail_hub + ``` +* **Alert Location:** On the root `azurerm_iothub` resource. + +## Involved Resource + +* `azurerm_iothub` +* `azurerm_iot_security_solution` + +## Solution + +To fix this risk, make sure to define an `azurerm_iot_security_solution` resource and include the IoT Hub ID in the `iothub_ids` attribute. + +```terraform +resource "azurerm_iothub" "example" { + name = "secure-iothub" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + + sku { + name = "S1" + capacity = "1" + } +} + +# SOLUTION: Define the security solution and link the Hub +resource "azurerm_iot_security_solution" "example" { + name = "iot-security-solution" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + display_name = "Iot Security Solution" + + iothub_ids = [azurerm_iothub.example.id] +} diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego index e6d34c49b56..89f9d92cca4 100644 --- a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: IoT Hub sin solución de seguridad (azurerm_iot_security_solution) asociada. +# RULE 1: IoT Hub without an associated security solution (azurerm_iot_security_solution). CxPolicy[result] { doc := input.document[i] iot_hub := doc.resource.azurerm_iothub[hub_name] diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/README.md b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/README.md index 520e46cf594..7cfdd5df575 100644 --- a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/README.md +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/README.md @@ -1,64 +1,64 @@ -# Regla KICS: Key Vault Key Rotation Disabled - -## Descripción General - -Esta regla de KICS verifica que las claves criptográficas almacenadas en Azure Key Vault (`azurerm_key_vault_key`) tengan configurada una política de rotación automática. - -La rotación automática de claves es una práctica de seguridad esencial que limita la cantidad de datos cifrados con una sola versión de clave y reduce significativamente el impacto en caso de que una clave se vea comprometida. Configurar una política de rotación asegura que las claves se renueven de forma proactiva sin intervención manual, garantizando la continuidad operativa y el cumplimiento de estándares de seguridad como PCI-DSS o HIPAA. - -## Lógica de la Regla - -La política analiza el recurso `azurerm_key_vault_key` realizando los siguientes pasos: -1. **Identificación de Claves:** Selecciona todos los recursos de tipo `azurerm_key_vault_key`. -2. **Verificación de Política:** Comprueba la existencia del bloque de configuración `rotation_policy`. -3. **Generación de Alerta:** Si el bloque está ausente, se considera que la clave no tiene una estrategia de rotación definida y se genera un hallazgo. - -## Caso de Fallo Detectado - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso Único: Clave sin política de rotación - -* **Descripción:** Se define una clave criptográfica en Key Vault pero se omite el bloque `rotation_policy`, dejando la responsabilidad de la rotación a procesos manuales o permitiendo que la clave permanezca indefinidamente. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_key_vault_key" "fail_key" { - name = "example-key" - key_vault_id = azurerm_key_vault.example.id - key_type = "RSA" - key_size = 2048 - key_opts = ["decrypt", "encrypt", "sign", "verify"] - - # El recurso carece de la configuración rotation_policy - } - ``` -* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_key_vault_key`. - -## Recurso Involucrado - -* `azurerm_key_vault_key` - -## Solución - -Para solucionar este riesgo, añada el bloque `rotation_policy` definiendo el tiempo de expiración y las reglas de rotación automática deseadas. - -```terraform -resource "azurerm_key_vault_key" "secure_key" { - name = "example-key" - key_vault_id = azurerm_key_vault.example.id - key_type = "RSA" - key_size = 2048 - key_opts = ["decrypt", "encrypt", "sign", "verify"] - - # SOLUCIÓN: Definir política de rotación automática - rotation_policy { - expire_after = "P90D" - notify_before_expiry = "P29D" - - automatic { - time_before_expiry = "P30D" - } - } -} \ No newline at end of file +# KICS Rule: Key Vault Key Rotation Disabled + +## General Description + +This KICS rule verifies that cryptographic keys stored in Azure Key Vault (`azurerm_key_vault_key`) have an automatic rotation policy configured. + +Automatic key rotation is an essential security practice that limits the amount of data encrypted with a single key version and significantly reduces the impact if a key is compromised. Configuring a rotation policy ensures that keys are proactively renewed without manual intervention, guaranteeing operational continuity and compliance with security standards such as PCI-DSS or HIPAA. + +## Rule Logic + +The policy analyzes the `azurerm_key_vault_key` resource by performing the following steps: +1. **Key Identification:** Selects all resources of type `azurerm_key_vault_key`. +2. **Policy Verification:** Checks for the existence of the `rotation_policy` configuration block. +3. **Alert Generation:** If the block is absent, the key is considered to have no defined rotation strategy and a finding is generated. + +## Detected Failure Case + +The following describes the scenario this policy will detect. + +--- + +### Single Case: Key without Rotation Policy + +* **Description:** A cryptographic key is defined in Key Vault but the `rotation_policy` block is omitted, leaving the rotation responsibility to manual processes or allowing the key to remain indefinitely. +* **Example of Problematic Terraform Code:** + ```terraform + resource "azurerm_key_vault_key" "fail_key" { + name = "example-key" + key_vault_id = azurerm_key_vault.example.id + key_type = "RSA" + key_size = 2048 + key_opts = ["decrypt", "encrypt", "sign", "verify"] + + # The resource lacks the rotation_policy configuration + } + ``` +* **Alert Location:** On the root `azurerm_key_vault_key` resource. + +## Involved Resource + +* `azurerm_key_vault_key` + +## Solution + +To fix this risk, add the `rotation_policy` block defining the expiry time and the desired automatic rotation rules. + +```terraform +resource "azurerm_key_vault_key" "secure_key" { + name = "example-key" + key_vault_id = azurerm_key_vault.example.id + key_type = "RSA" + key_size = 2048 + key_opts = ["decrypt", "encrypt", "sign", "verify"] + + # SOLUTION: Define automatic rotation policy + rotation_policy { + expire_after = "P90D" + notify_before_expiry = "P29D" + + automatic { + time_before_expiry = "P30D" + } + } +} diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego index 9ff8c50a62f..e6331167f33 100644 --- a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: La clave del Key Vault no tiene política de rotación configurada. +# RULE 1: The Key Vault key does not have a rotation policy configured. CxPolicy[result] { doc := input.document[i] key := doc.resource.azurerm_key_vault_key[name] diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/README.md index 8cb4d412bcc..a35e7ef8af0 100644 --- a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/README.md +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/README.md @@ -1,60 +1,60 @@ -# Regla KICS: Azure Managed Lustre Not Encrypted with CMK - -## Descripción General - -Esta regla de KICS verifica que los sistemas de archivos **Azure Managed Lustre** (`azurerm_managed_lustre_file_system`) estén configurados para utilizar claves gestionadas por el cliente (**Customer-Managed Keys - CMK**) para el cifrado de datos en reposo. - -Por defecto, Azure cifra los datos en Lustre utilizando claves gestionadas por la plataforma. Para cumplir con requisitos de soberanía de datos y gobernanza, se recomienda el uso de CMK mediante el bloque `encryption_key`. Esto otorga a las organizaciones control total sobre el ciclo de vida de la clave, permitiendo la rotación y revocación selectiva del acceso a los datos de alto rendimiento almacenados en el sistema de archivos. - -## Lógica de la Regla - -La política analiza el recurso `azurerm_managed_lustre_file_system` validando la siguiente condición: -1. **Presencia del Bloque de Cifrado:** Se verifica la existencia del bloque `encryption_key`. Si este bloque no está definido, el sistema de archivos utiliza por defecto el cifrado gestionado por Azure. - -## Caso de Fallo Detectado - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso Único: Uso de Claves Gestionadas por la Plataforma (Bloque Ausente) - -* **Descripción:** El sistema de archivos Lustre se define sin el bloque de configuración de cifrado por cliente, lo que delega la protección de los datos a las claves por defecto de la plataforma. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_managed_lustre_file_system" "example_insecure" { - name = "insecure-lustre" - resource_group_name = "rg-example" - location = "West Europe" - sku_name = "AMLFS-Durable-Premium-250" - subnet_id = azurerm_subnet.example.id - storage_capacity_in_tb = 48 - - # El recurso carece del bloque encryption_key - } - ``` -* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_managed_lustre_file_system`. - -## Recurso Involucrado - -* `azurerm_managed_lustre_file_system` - -## Solución - -Para solucionar este riesgo, defina el bloque `encryption_key` proporcionando la URL de la clave y el ID del Key Vault de origen. - -```terraform -resource "azurerm_managed_lustre_file_system" "secure_lustre" { - name = "secure-lustre" - resource_group_name = "rg-example" - location = "West Europe" - sku_name = "AMLFS-Durable-Premium-250" - subnet_id = azurerm_subnet.example.id - storage_capacity_in_tb = 48 - - # SOLUCIÓN: Configurar cifrado con CMK - encryption_key { - key_url = azurerm_key_vault_key.example.id - source_vault_id = azurerm_key_vault.example.id - } -} \ No newline at end of file +# KICS Rule: Azure Managed Lustre Not Encrypted with CMK + +## General Description + +This KICS rule verifies that **Azure Managed Lustre** file systems (`azurerm_managed_lustre_file_system`) are configured to use **Customer-Managed Keys (CMK)** for data encryption at rest. + +By default, Azure encrypts data in Lustre using platform-managed keys. To meet data sovereignty and governance requirements, the use of CMK via the `encryption_key` block is recommended. This gives organizations full control over the key lifecycle, allowing rotation and selective revocation of access to the high-performance data stored in the file system. + +## Rule Logic + +The policy analyzes the `azurerm_managed_lustre_file_system` resource by validating the following condition: +1. **Encryption Block Presence:** The existence of the `encryption_key` block is verified. If this block is not defined, the file system defaults to Azure-managed encryption. + +## Detected Failure Case + +The following describes the scenario this policy will detect. + +--- + +### Single Case: Use of Platform-Managed Keys (Block Absent) + +* **Description:** The Lustre file system is defined without the customer encryption configuration block, delegating data protection to the platform's default keys. +* **Example of Problematic Terraform Code:** + ```terraform + resource "azurerm_managed_lustre_file_system" "example_insecure" { + name = "insecure-lustre" + resource_group_name = "rg-example" + location = "West Europe" + sku_name = "AMLFS-Durable-Premium-250" + subnet_id = azurerm_subnet.example.id + storage_capacity_in_tb = 48 + + # The resource lacks the encryption_key block + } + ``` +* **Alert Location:** On the root `azurerm_managed_lustre_file_system` resource. + +## Involved Resource + +* `azurerm_managed_lustre_file_system` + +## Solution + +To fix this risk, define the `encryption_key` block providing the key URL and the source Key Vault ID. + +```terraform +resource "azurerm_managed_lustre_file_system" "secure_lustre" { + name = "secure-lustre" + resource_group_name = "rg-example" + location = "West Europe" + sku_name = "AMLFS-Durable-Premium-250" + subnet_id = azurerm_subnet.example.id + storage_capacity_in_tb = 48 + + # SOLUTION: Configure encryption with CMK + encryption_key { + key_url = azurerm_key_vault_key.example.id + source_vault_id = azurerm_key_vault.example.id + } +} diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego index c757a60bbc2..9347a6f0a1f 100644 --- a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: El bloque 'encryption_key' no está definido. +# RULE 1: The 'encryption_key' block is not defined. CxPolicy[result] { doc := input.document[i] lustre := doc.resource.azurerm_managed_lustre_file_system[name] diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/README.md b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/README.md index 2999db498d9..d387e7ae51d 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/README.md +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/README.md @@ -1,59 +1,59 @@ -# Regla KICS: MySQL Audit Log Enabled (Manual) - -## Descripción General - -Esta regla de KICS actúa como un control manual para asegurar que el parámetro de servidor `audit_log_enabled` esté configurado en `ON` en las instancias de **Azure Database for MySQL**. - -Los registros de auditoría son fundamentales para la observabilidad y la seguridad de la base de datos. Permiten rastrear eventos específicos, como intentos de conexión, ejecución de consultas DDL y cambios en privilegios de usuario. Debido a que en Azure MySQL estos parámetros pueden gestionarse de forma externa al recurso del servidor (ya sea por el portal o mediante recursos de configuración independientes), se requiere una validación manual para confirmar el cumplimiento. - -## Lógica de la Regla - -Dado que la configuración de auditoría no reside obligatoriamente dentro del bloque principal del servidor MySQL en Terraform, el análisis estático se centra en: -1. **Identificación de Recursos:** La regla localiza todos los recursos de tipo `azurerm_mssql_server` y `azurerm_mysql_flexible_server`. -2. **Recordatorio de Auditoría:** Genera un hallazgo de severidad informativa para alertar al administrador de la necesidad de verificar el estado del parámetro `audit_log_enabled`. - -## Caso de Fallo Detectado - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso Único: Verificación Manual Requerida - -* **Descripción:** Se detecta la presencia de un servidor MySQL. Dado que el estado de la auditoría no siempre es verificable estáticamente desde el recurso del servidor, se solicita revisión manual. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_mssql_server" "example_insecure" { - name = "mysql-server-audit-check" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - # El estado de audit_log_enabled no es visible aquí. - } - ``` -* **Ubicación de la Alerta:** Sobre el recurso del servidor MySQL detectado. - -## Recurso Involucrado - -* `azurerm_mssql_server` -* `azurerm_mysql_flexible_server` - -## Solución - -Existen dos métodos para asegurar que la auditoría esté habilitada: - -### Opción A: Verificación Manual (Portal de Azure) -1. Navegue a su servidor MySQL en el Portal de Azure. -2. Acceda a la sección **Parámetros del servidor**. -3. Busque el parámetro `audit_log_enabled` y confirme que su valor sea `ON`. - -### Opción B: Configuración como Código (Recomendado) -Utilice el recurso `azurerm_mysql_configuration` (para servidores Single Server) o `azurerm_mysql_flexible_server_configuration` (para Flexible Server) para forzar el parámetro: - -```terraform -# Ejemplo para MySQL Single Server -resource "azurerm_mysql_configuration" "audit_log" { - name = "audit_log_enabled" - resource_group_name = azurerm_resource_group.example.name - server_name = azurerm_mssql_server.example.name - value = "ON" -} \ No newline at end of file +# KICS Rule: MySQL Audit Log Enabled (Manual) + +## General Description + +This KICS rule acts as a manual control to ensure that the server parameter `audit_log_enabled` is set to `ON` in **Azure Database for MySQL** instances. + +Audit logs are essential for database observability and security. They allow tracking of specific events, such as connection attempts, DDL query execution, and user privilege changes. Because in Azure MySQL these parameters can be managed externally to the server resource (either through the portal or via independent configuration resources), manual validation is required to confirm compliance. + +## Rule Logic + +Since the audit configuration does not necessarily reside within the main MySQL server block in Terraform, the static analysis focuses on: +1. **Resource Identification:** The rule locates all resources of type `azurerm_mssql_server` and `azurerm_mysql_flexible_server`. +2. **Audit Reminder:** Generates an informational severity finding to alert the administrator of the need to verify the status of the `audit_log_enabled` parameter. + +## Detected Failure Case + +The following describes the scenario this policy will detect. + +--- + +### Single Case: Manual Verification Required + +* **Description:** The presence of a MySQL server is detected. Since the audit status is not always statically verifiable from the server resource, a manual review is requested. +* **Example of Problematic Terraform Code:** + ```terraform + resource "azurerm_mssql_server" "example_insecure" { + name = "mysql-server-audit-check" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + # The status of audit_log_enabled is not visible here. + } + ``` +* **Alert Location:** On the detected MySQL server resource. + +## Involved Resource + +* `azurerm_mssql_server` +* `azurerm_mysql_flexible_server` + +## Solution + +There are two methods to ensure that auditing is enabled: + +### Option A: Manual Verification (Azure Portal) +1. Navigate to your MySQL server in the Azure Portal. +2. Go to the **Server parameters** section. +3. Search for the `audit_log_enabled` parameter and confirm its value is `ON`. + +### Option B: Configuration as Code (Recommended) +Use the `azurerm_mysql_configuration` resource (for Single Server) or `azurerm_mysql_flexible_server_configuration` (for Flexible Server) to enforce the parameter: + +```terraform +# Example for MySQL Single Server +resource "azurerm_mysql_configuration" "audit_log" { + name = "audit_log_enabled" + resource_group_name = azurerm_resource_group.example.name + server_name = azurerm_mssql_server.example.name + value = "ON" +} diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego index 0023adb1aec..8c719c49278 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego @@ -4,7 +4,7 @@ import data.generic.terraform as tf_lib targets := {"azurerm_mssql_server", "azurerm_mysql_flexible_server"} -# REGLA MANUAL: Detecta servidores MySQL para solicitar verificación de logs de auditoría. +# MANUAL RULE: Detects MySQL servers to request verification of audit logs. CxPolicy[result] { doc := input.document[i] diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/README.md b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/README.md index ade2b20eddb..4b55e834e7f 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/README.md +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/README.md @@ -1,59 +1,59 @@ -# Regla KICS: MySQL Audit Log Events Connection (Manual) - -## Descripción General - -Esta regla de KICS actúa como un control manual para verificar que el parámetro de servidor `audit_log_events` incluya el valor `CONNECTION` en los servidores de **Azure Database for MySQL**. - -El registro de los eventos de tipo `CONNECTION` es una pieza fundamental de la estrategia de seguridad y cumplimiento. Permite a los administradores y auditores rastrear quién accede a la base de datos, detectar ataques de fuerza bruta (intentos fallidos) y auditar sesiones sospechosas. Sin esta configuración, se pierde visibilidad sobre el acceso inicial a los recursos de datos, dificultando la respuesta ante incidentes. - -## Lógica de la Regla - -Debido a que el análisis estático no siempre puede garantizar la verificación de una cadena de texto dentro de un recurso de configuración independiente (`azurerm_mysql_configuration`), esta regla aplica un enfoque preventivo: -1. **Identificación de Recursos:** Detecta todas las instancias de `azurerm_mssql_server` y `azurerm_mysql_flexible_server`. -2. **Recordatorio de Seguridad:** Genera una alerta informativa para que el auditor verifique específicamente que el evento de conexión esté siendo capturado. - -## Caso de Fallo Detectado - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso Único: Verificación Manual Requerida - -* **Descripción:** Se detecta un servidor MySQL aprovisionado. KICS emite una alerta para asegurar que los tipos de eventos auditados incluyan las conexiones, ya que esta configuración puede estar delegada a otros recursos o al portal. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_mssql_server" "example_audit_check" { - name = "mysql-server-connection-check" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - # El contenido de audit_log_events no es verificable aquí. - } - ``` -* **Ubicación de la Alerta:** Sobre el recurso del servidor MySQL detectado. - -## Recurso Involucrado - -* `azurerm_mssql_server` -* `azurerm_mysql_flexible_server` - -## Solución - -### Opción A: Verificación Manual (Portal de Azure) -1. Navegue al servidor MySQL en el Portal de Azure. -2. Vaya a la sección **Parámetros del servidor**. -3. Localice el parámetro `audit_log_events`. -4. Asegúrese de que entre los valores seleccionados se incluya `CONNECTION`. - -### Opción B: Configuración mediante Terraform -Asegúrese de incluir explícitamente el valor en el recurso de configuración: - -```terraform -resource "azurerm_mysql_configuration" "audit_events" { - name = "audit_log_events" - resource_group_name = azurerm_resource_group.example.name - server_name = azurerm_mssql_server.example.name - - # SOLUCIÓN: Incluir CONNECTION en la lista de eventos - value = "CONNECTION,QUERY,DDL" -} \ No newline at end of file +# KICS Rule: MySQL Audit Log Events Connection (Manual) + +## General Description + +This KICS rule acts as a manual control to verify that the server parameter `audit_log_events` includes the value `CONNECTION` in **Azure Database for MySQL** servers. + +Logging `CONNECTION` type events is a fundamental piece of the security and compliance strategy. It allows administrators and auditors to track who accesses the database, detect brute force attacks (failed attempts), and audit suspicious sessions. Without this configuration, visibility into initial access to data resources is lost, making incident response more difficult. + +## Rule Logic + +Because static analysis cannot always guarantee verification of a text string within an independent configuration resource (`azurerm_mysql_configuration`), this rule applies a preventive approach: +1. **Resource Identification:** Detects all instances of `azurerm_mssql_server` and `azurerm_mysql_flexible_server`. +2. **Security Reminder:** Generates an informational alert for the auditor to specifically verify that connection events are being captured. + +## Detected Failure Case + +The following describes the scenario this policy will detect. + +--- + +### Single Case: Manual Verification Required + +* **Description:** A provisioned MySQL server is detected. KICS issues an alert to ensure that the audited event types include connections, since this configuration may be delegated to other resources or the portal. +* **Example of Problematic Terraform Code:** + ```terraform + resource "azurerm_mssql_server" "example_audit_check" { + name = "mysql-server-connection-check" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + # The content of audit_log_events is not verifiable here. + } + ``` +* **Alert Location:** On the detected MySQL server resource. + +## Involved Resource + +* `azurerm_mssql_server` +* `azurerm_mysql_flexible_server` + +## Solution + +### Option A: Manual Verification (Azure Portal) +1. Navigate to the MySQL server in the Azure Portal. +2. Go to the **Server parameters** section. +3. Locate the `audit_log_events` parameter. +4. Ensure that `CONNECTION` is included among the selected values. + +### Option B: Configuration via Terraform +Make sure to explicitly include the value in the configuration resource: + +```terraform +resource "azurerm_mysql_configuration" "audit_events" { + name = "audit_log_events" + resource_group_name = azurerm_resource_group.example.name + server_name = azurerm_mssql_server.example.name + + # SOLUTION: Include CONNECTION in the list of events + value = "CONNECTION,QUERY,DDL" +} diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego index cfc0c13ccf1..5d64544e5a2 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego @@ -4,7 +4,7 @@ import data.generic.terraform as tf_lib targets := {"azurerm_mssql_server", "azurerm_mysql_flexible_server"} -# REGLA MANUAL: Detecta servidores MySQL para solicitar verificación del evento CONNECTION. +# MANUAL RULE: Detects MySQL servers to request verification of the CONNECTION event. CxPolicy[result] { doc := input.document[i] diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/README.md index fbdc28464c5..d644eaa261e 100644 --- a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/README.md +++ b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/README.md @@ -1,65 +1,65 @@ -# Regla KICS: NetApp Account CMK Encryption Disabled - -## Descripción General - -Esta regla de KICS verifica que las cuentas de **Azure NetApp Files** estén configuradas para utilizar claves gestionadas por el cliente (**Customer-Managed Keys - CMK**) para el cifrado de datos en reposo. - -Por defecto, Azure NetApp Files cifra los datos utilizando claves gestionadas por la plataforma Microsoft. Sin embargo, para cumplir con requisitos de cumplimiento normativo y soberanía de datos, se recomienda el uso de CMK. Esto permite a las organizaciones tener el control total sobre el ciclo de vida de las claves, incluyendo la rotación y la revocación de acceso, asegurando que los volúmenes de almacenamiento de alto rendimiento estén protegidos por claves bajo el control directo del cliente en Azure Key Vault. - -## Lógica de la Regla - -La política analiza la configuración de Terraform buscando dos métodos válidos de implementación de CMK: -1. **Configuración Inline:** Verifica si el recurso `azurerm_netapp_account` tiene un bloque `encryption` donde el atributo `key_source` sea explícitamente `Microsoft.KeyVault`. -2. **Recurso Independiente:** Verifica si existe un recurso `azurerm_netapp_account_encryption` vinculado al ID de la cuenta NetApp analizada. - -Si no se detecta ninguno de estos dos métodos, se genera una alerta indicando que la cuenta está operando con el cifrado predeterminado de la plataforma. - -## Caso de Fallo Detectado - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso Único: Configuración de Cifrado por Defecto (Platform Keys) - -* **Descripción:** Se define la cuenta de NetApp sin habilitar el uso de Key Vault para el cifrado, dejando los datos protegidos únicamente por las claves de Microsoft. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_netapp_account" "fail" { - name = "insecure-netapp-account" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - - # Falta la configuración de CMK (inline o recurso separado) - } - ``` -* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_netapp_account`. - -## Recursos Involucrados - -* `azurerm_netapp_account` -* `azurerm_netapp_account_encryption` - -## Solución - -Para solucionar este riesgo, asigne una identidad gestionada a la cuenta y utilice el recurso `azurerm_netapp_account_encryption` para vincular la clave del Key Vault. - -```terraform -resource "azurerm_netapp_account" "secure" { - name = "secure-netapp-account" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - - # 1. Asignar identidad - identity { - type = "UserAssigned" - identity_ids = [azurerm_user_assigned_identity.example.id] - } -} - -# 2. Configurar el cifrado CMK mediante el recurso dedicado -resource "azurerm_netapp_account_encryption" "secure_encryption" { - netapp_account_id = azurerm_netapp_account.secure.id - user_assigned_identity_id = azurerm_user_assigned_identity.example.id - encryption_key = azurerm_key_vault_key.example.versionless_id -} \ No newline at end of file +# KICS Rule: NetApp Account CMK Encryption Disabled + +## General Description + +This KICS rule verifies that **Azure NetApp Files** accounts are configured to use **Customer-Managed Keys (CMK)** for data encryption at rest. + +By default, Azure NetApp Files encrypts data using Microsoft platform-managed keys. However, to meet regulatory compliance and data sovereignty requirements, the use of CMK is recommended. This allows organizations to have full control over the key lifecycle, including rotation and access revocation, ensuring that high-performance storage volumes are protected by keys under the direct control of the customer in Azure Key Vault. + +## Rule Logic + +The policy analyzes the Terraform configuration looking for two valid CMK implementation methods: +1. **Inline Configuration:** Checks whether the `azurerm_netapp_account` resource has an `encryption` block where the `key_source` attribute is explicitly `Microsoft.KeyVault`. +2. **Standalone Resource:** Checks whether an `azurerm_netapp_account_encryption` resource exists linked to the analyzed NetApp account's ID. + +If neither of these two methods is detected, an alert is generated indicating that the account is operating with the platform's default encryption. + +## Detected Failure Case + +The following describes the scenario this policy will detect. + +--- + +### Single Case: Default Encryption Configuration (Platform Keys) + +* **Description:** The NetApp account is defined without enabling Key Vault for encryption, leaving the data protected only by Microsoft keys. +* **Example of Problematic Terraform Code:** + ```terraform + resource "azurerm_netapp_account" "fail" { + name = "insecure-netapp-account" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + + # Missing CMK configuration (inline or separate resource) + } + ``` +* **Alert Location:** On the root `azurerm_netapp_account` resource. + +## Involved Resources + +* `azurerm_netapp_account` +* `azurerm_netapp_account_encryption` + +## Solution + +To fix this risk, assign a managed identity to the account and use the `azurerm_netapp_account_encryption` resource to link the Key Vault key. + +```terraform +resource "azurerm_netapp_account" "secure" { + name = "secure-netapp-account" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + + # 1. Assign identity + identity { + type = "UserAssigned" + identity_ids = [azurerm_user_assigned_identity.example.id] + } +} + +# 2. Configure CMK encryption via the dedicated resource +resource "azurerm_netapp_account_encryption" "secure_encryption" { + netapp_account_id = azurerm_netapp_account.secure.id + user_assigned_identity_id = azurerm_user_assigned_identity.example.id + encryption_key = azurerm_key_vault_key.example.versionless_id +} diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego index 6a686cfe748..4965d4fde46 100644 --- a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego @@ -19,7 +19,7 @@ has_inline_encryption(account) { account.encryption.key_source == "Microsoft.KeyVault" } -# REGLA 1: La cuenta NetApp utiliza Platform-Managed Keys (falta configuración CMK). +# RULE 1: The NetApp account uses Platform-Managed Keys (CMK configuration is missing). CxPolicy[result] { doc := input.document[i] account := doc.resource.azurerm_netapp_account[name] diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/README.md b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/README.md index 4c089125f9b..64aae415fac 100644 --- a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/README.md +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/README.md @@ -1,67 +1,67 @@ -# Regla KICS: Azure PaaS Services Private Endpoint Disabled (Master) - -## Descripción General - -Esta es una regla consolidada (**Regla Maestra**) diseñada para asegurar que los servicios PaaS críticos de Azure estén protegidos mediante el uso de **Private Endpoints**. - -Los Private Endpoints (Puntos de Conexión Privados) son un componente esencial de la seguridad perimetral en Azure. Permiten que los servicios (como bases de datos, almacenamiento o bóvedas de claves) se integren directamente en una Red Virtual (VNet). Al asignar una dirección IP privada del espacio de la VNet al servicio, se elimina la necesidad de exponer dichos recursos a la internet pública, reduciendo drásticamente la superficie de ataque y previniendo la exfiltración de datos. - -## Lógica de la Regla - -La política analiza de forma exhaustiva los recursos definidos en Terraform buscando una vinculación válida: -1. **Recursos Objetivo:** La regla monitorea una lista extensa de servicios, incluyendo `azurerm_storage_account`, `azurerm_mssql_server`, `azurerm_cosmosdb_account`, `azurerm_key_vault` y otros servicios de datos y mensajería. -2. **Validación de Vínculo:** Para cada recurso detectado, busca la existencia de un recurso `azurerm_private_endpoint` que lo referencia a través del atributo `private_connection_resource_id`. -3. **Resultado:** Si el recurso PaaS existe pero no hay un endpoint privado asociado en el mismo contexto de código, se genera una alerta. - -## Limitaciones del Análisis Estático - -Es importante notar que esta regla valida la configuración **dentro del mismo archivo o estado de Terraform**. Debido a la naturaleza del análisis estático: -* No puede validar conexiones si el recurso se crea en una suscripción distinta o se gestiona en un estado de Terraform separado. -* Podría generar falsos positivos si el endpoint se define mediante módulos externos cuyas variables no son resueltas por el motor de escaneo. - -## Caso de Fallo Detectado - -A continuación se describe el escenario principal que esta política detectará. - ---- - -### Caso Único: Recurso PaaS Aislado (Sin Endpoint Privado) - -* **Descripción:** Se ha definido un servicio crítico (ej. Azure SQL o Storage Account) pero no se ha aprovisionado el endpoint privado que garantice que el tráfico sea interno a la VNet. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_storage_account" "example_insecure" { - name = "stinsecuredata" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "LRS" - - # El recurso existe pero carece de un azurerm_private_endpoint vinculado - } - ``` -* **Ubicación de la Alerta:** Sobre el recurso PaaS identificado (Storage, SQL, Key Vault, etc.). - -## Recursos Involucrados - -* `azurerm_private_endpoint` -* Servicios PaaS (Storage, SQL, Cosmos, KeyVault, ACR, ServiceBus, etc.) - -## Solución - -Para solucionar este hallazgo, debe crear un recurso `azurerm_private_endpoint` y vincularlo al ID del recurso PaaS mediante el bloque `private_service_connection`. - -```terraform -resource "azurerm_private_endpoint" "example_secure" { - name = "pe-storage" - location = azurerm_resource_group.example.location - resource_group_name = azurerm_resource_group.example.name - subnet_id = azurerm_subnet.example.id - - private_service_connection { - name = "psc-storage" - private_connection_resource_id = azurerm_storage_account.example_insecure.id - is_manual_connection = false - subresource_names = ["blob"] - } -} \ No newline at end of file +# KICS Rule: Azure PaaS Services Private Endpoint Disabled (Master) + +## General Description + +This is a consolidated rule (**Master Rule**) designed to ensure that critical Azure PaaS services are protected through the use of **Private Endpoints**. + +Private Endpoints are an essential component of perimeter security in Azure. They allow services (such as databases, storage, or key vaults) to integrate directly into a Virtual Network (VNet). By assigning a private IP address from the VNet's address space to the service, the need to expose those resources to the public internet is eliminated, drastically reducing the attack surface and preventing data exfiltration. + +## Rule Logic + +The policy comprehensively analyzes resources defined in Terraform looking for a valid link: +1. **Target Resources:** The rule monitors an extensive list of services, including `azurerm_storage_account`, `azurerm_mssql_server`, `azurerm_cosmosdb_account`, `azurerm_key_vault`, and other data and messaging services. +2. **Link Validation:** For each detected resource, it looks for the existence of an `azurerm_private_endpoint` resource that references it through the `private_connection_resource_id` attribute. +3. **Result:** If the PaaS resource exists but there is no associated private endpoint in the same code context, an alert is generated. + +## Static Analysis Limitations + +It is important to note that this rule validates the configuration **within the same Terraform file or state**. Due to the nature of static analysis: +* It cannot validate connections if the resource is created in a different subscription or managed in a separate Terraform state. +* It may generate false positives if the endpoint is defined through external modules whose variables are not resolved by the scanning engine. + +## Detected Failure Case + +The following describes the main scenario this policy will detect. + +--- + +### Single Case: Isolated PaaS Resource (No Private Endpoint) + +* **Description:** A critical service (e.g., Azure SQL or Storage Account) has been defined but the private endpoint that ensures traffic is internal to the VNet has not been provisioned. +* **Example of Problematic Terraform Code:** + ```terraform + resource "azurerm_storage_account" "example_insecure" { + name = "stinsecuredata" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "LRS" + + # The resource exists but lacks a linked azurerm_private_endpoint + } + ``` +* **Alert Location:** On the identified PaaS resource (Storage, SQL, Key Vault, etc.). + +## Involved Resources + +* `azurerm_private_endpoint` +* PaaS Services (Storage, SQL, Cosmos, KeyVault, ACR, ServiceBus, etc.) + +## Solution + +To fix this finding, you must create an `azurerm_private_endpoint` resource and link it to the PaaS resource ID via the `private_service_connection` block. + +```terraform +resource "azurerm_private_endpoint" "example_secure" { + name = "pe-storage" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + subnet_id = azurerm_subnet.example.id + + private_service_connection { + name = "psc-storage" + private_connection_resource_id = azurerm_storage_account.example_insecure.id + is_manual_connection = false + subresource_names = ["blob"] + } +} diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego index e012f8ad5e4..2aab0d37bb3 100644 --- a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego @@ -20,7 +20,7 @@ targets := { "azurerm_search_service" } -# REGLA MAESTRA: Verifica si los recursos de la lista targets tienen un Private Endpoint vinculado. +# MASTER RULE: Checks whether resources in the targets list have a linked Private Endpoint. CxPolicy[result] { doc := input.document[i] diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/README.md b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/README.md index f5ae5d05d63..3aca3e0d337 100644 --- a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/README.md +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/README.md @@ -1,69 +1,69 @@ -# Regla KICS: Production Workload using Basic or Consumption SKU - -## Descripción General - -Esta regla identifica recursos de Azure configurados con niveles de precios (SKUs) de tipo **Basic**, **Free** o **Consumption**. - -Aunque estos niveles son ideales para entornos de desarrollo, aprendizaje o pruebas de concepto (PoC), carecen de características fundamentales necesarias para entornos de producción. El uso de estos SKUs en producción compromete la fiabilidad del servicio debido a la ausencia de Acuerdos de Nivel de Servicio (SLA) garantizados, falta de soporte para integración con redes virtuales (VNet), ausencia de slots de implementación y latencias imprevistas ("cold starts") en modelos de consumo serverless. - -## Lógica de la Regla - -La política audita los siguientes recursos en la configuración de Terraform: -1. **Service Plans (`azurerm_service_plan`):** Alerta si el atributo `sku_name` se establece en niveles no productivos como B1-B3, F1, FREE o Y1. -2. **API Management (`azurerm_api_management`):** Alerta si el atributo `sku_name` coincide con patrones de tipo "Basic" o "Consumption". - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Service Plan en Nivel No-Productivo - -* **Descripción:** Se detecta un plan de App Service configurado en nivel Basic o Free, lo cual limita la disponibilidad y las capacidades de red del servicio. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_service_plan" "fail_plan" { - name = "example-basic-plan" - resource_group_name = "rg-production" - location = "West Europe" - os_type = "Linux" - sku_name = "B1" # <-- FALLO: Nivel Basic - } - ``` -* **Ubicación de la Alerta:** Atributo `sku_name`. - ---- - -### Caso 2: API Management en Modo Consumo - -* **Descripción:** Se detecta una instancia de APIM en nivel Consumption (Serverless), lo que puede afectar al rendimiento y carece de aislamiento de red. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_api_management" "fail_apim" { - name = "example-apim" - sku_name = "Consumption_0" # <-- FALLO: Nivel Consumption - # ... resto de la configuración ... - } - ``` -* **Ubicación de la Alerta:** Atributo `sku_name`. - -## Recurso Involucrado - -* `azurerm_service_plan` -* `azurerm_api_management` - -## Solución - -Actualice el SKU del recurso a un nivel orientado a producción, como **Standard (S)** o **Premium (P)**, para garantizar el SLA y las funciones de red necesarias. - -```terraform -resource "azurerm_service_plan" "secure_production" { - name = "prod-service-plan" - resource_group_name = "rg-production" - location = "West Europe" - os_type = "Linux" - - # SOLUCIÓN: Usar un nivel Standard o superior - sku_name = "S1" -} \ No newline at end of file +# KICS Rule: Production Workload using Basic or Consumption SKU + +## General Description + +This rule identifies Azure resources configured with **Basic**, **Free**, or **Consumption** pricing tiers (SKUs). + +Although these tiers are ideal for development, learning, or proof-of-concept (PoC) environments, they lack fundamental features required for production environments. Using these SKUs in production compromises service reliability due to the absence of guaranteed Service Level Agreements (SLAs), lack of support for virtual network (VNet) integration, absence of deployment slots, and unexpected latencies ("cold starts") in serverless consumption models. + +## Rule Logic + +The policy audits the following resources in the Terraform configuration: +1. **Service Plans (`azurerm_service_plan`):** Alerts if the `sku_name` attribute is set to non-production tiers such as B1-B3, F1, FREE, or Y1. +2. **API Management (`azurerm_api_management`):** Alerts if the `sku_name` attribute matches patterns of type "Basic" or "Consumption". + +## Detected Failure Cases + +The following describes the scenarios this policy will detect. + +--- + +### Case 1: Service Plan at Non-Production Tier + +* **Description:** An App Service plan is detected configured at Basic or Free tier, which limits the availability and network capabilities of the service. +* **Example of Problematic Terraform Code:** + ```terraform + resource "azurerm_service_plan" "fail_plan" { + name = "example-basic-plan" + resource_group_name = "rg-production" + location = "West Europe" + os_type = "Linux" + sku_name = "B1" # <-- FAILURE: Basic Tier + } + ``` +* **Alert Location:** `sku_name` attribute. + +--- + +### Case 2: API Management in Consumption Mode + +* **Description:** An APIM instance is detected at the Consumption (Serverless) tier, which may affect performance and lacks network isolation. +* **Example of Problematic Terraform Code:** + ```terraform + resource "azurerm_api_management" "fail_apim" { + name = "example-apim" + sku_name = "Consumption_0" # <-- FAILURE: Consumption Tier + # ... rest of configuration ... + } + ``` +* **Alert Location:** `sku_name` attribute. + +## Involved Resource + +* `azurerm_service_plan` +* `azurerm_api_management` + +## Solution + +Update the resource SKU to a production-oriented tier, such as **Standard (S)** or **Premium (P)**, to guarantee the SLA and the necessary network features. + +```terraform +resource "azurerm_service_plan" "secure_production" { + name = "prod-service-plan" + resource_group_name = "rg-production" + location = "West Europe" + os_type = "Linux" + + # SOLUTION: Use a Standard tier or higher + sku_name = "S1" +} diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego index 8da9f5e92c1..486843a915d 100644 --- a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: Azure Service Plan usando SKU Basic (B), Free (F) o Consumption (Y1). +# RULE 1: Azure Service Plan using Basic (B), Free (F), or Consumption (Y1) SKU. CxPolicy[result] { doc := input.document[i] plan := doc.resource.azurerm_service_plan[name] @@ -21,7 +21,7 @@ CxPolicy[result] { } } -# REGLA 2: Azure API Management usando SKU Basic o Consumption. +# RULE 2: Azure API Management using Basic or Consumption SKU. CxPolicy[result] { doc := input.document[i] apim := doc.resource.azurerm_api_management[name] diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/README.md index e4cf7cd3af5..f43c35658bc 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/README.md +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/README.md @@ -1,61 +1,61 @@ -# Regla KICS: Recovery Services Vault CMK Encryption Disabled - -## Descripción General - -Esta regla de KICS verifica que los almacenes de **Recovery Services Vault** (utilizados para Azure Backup y Azure Site Recovery) estén configurados para utilizar claves gestionadas por el cliente (**Customer-Managed Keys - CMK**) para el cifrado de datos en reposo. - -Por defecto, los datos respaldados se cifran mediante claves gestionadas por la plataforma de Microsoft. Sin embargo, para cumplir con requisitos de cumplimiento normativo y garantizar la soberanía de los datos, las organizaciones deben utilizar sus propias claves almacenadas en Azure Key Vault. Esto permite un control total sobre la rotación de claves, las políticas de acceso y la capacidad de revocar el acceso a los datos de respaldo en caso de necesidad. - -## Lógica de la Regla - -La política analiza el recurso `azurerm_recovery_services_vault` validando la siguiente condición técnica: -1. **Presencia del Bloque de Cifrado:** Se comprueba la existencia del bloque `encryption`. La ausencia de este bloque implica que el almacén utiliza el cifrado predeterminado gestionado por la plataforma, lo cual no cumple con los requisitos de CMK. - -## Caso de Fallo Detectado - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso Único: Uso de Claves de la Plataforma (Cifrado por Defecto) - -* **Descripción:** Se define el Recovery Services Vault sin el bloque de configuración de cifrado por cliente, delegando la protección de los datos a las claves automáticas de Azure. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_recovery_services_vault" "fail_vault" { - name = "insecure-vault" - location = "West Europe" - resource_group_name = "rg-production" - sku = "Standard" - - # El recurso carece del bloque encryption {} - } - ``` -* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_recovery_services_vault`. - -## Recurso Involucrado - -* `azurerm_recovery_services_vault` - -## Solución - -Para solucionar este hallazgo, debe habilitar una identidad gestionada en el Vault y configurar el bloque `encryption` proporcionando obligatoriamente el `key_id` de Azure Key Vault. - -```terraform -resource "azurerm_recovery_services_vault" "secure_vault" { - name = "secure-recovery-vault" - location = azurerm_resource_group.example.location - resource_group_name = azurerm_resource_group.example.name - sku = "Standard" - - # 1. Habilitar identidad para acceso al Key Vault - identity { - type = "SystemAssigned" - } - - # 2. Configurar el cifrado CMK (key_id es obligatorio en este bloque) - encryption { - key_id = azurerm_key_vault_key.example.id - use_system_assigned_identity = true - } -} \ No newline at end of file +# KICS Rule: Recovery Services Vault CMK Encryption Disabled + +## General Description + +This KICS rule verifies that **Recovery Services Vault** vaults (used for Azure Backup and Azure Site Recovery) are configured to use **Customer-Managed Keys (CMK)** for data encryption at rest. + +By default, backed-up data is encrypted using Microsoft platform-managed keys. However, to comply with regulatory requirements and ensure data sovereignty, organizations must use their own keys stored in Azure Key Vault. This allows full control over key rotation, access policies, and the ability to revoke access to backup data when needed. + +## Rule Logic + +The policy analyzes the `azurerm_recovery_services_vault` resource by validating the following technical condition: +1. **Presence of the Encryption Block:** The existence of the `encryption` block is checked. The absence of this block implies that the vault uses the default platform-managed encryption, which does not meet CMK requirements. + +## Detected Failure Case + +The following describes the scenario that this policy will detect. + +--- + +### Single Case: Use of Platform Keys (Default Encryption) + +* **Description:** The Recovery Services Vault is defined without the customer encryption configuration block, delegating data protection to Azure's automatic keys. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_recovery_services_vault" "fail_vault" { + name = "insecure-vault" + location = "West Europe" + resource_group_name = "rg-production" + sku = "Standard" + + # The resource lacks the encryption {} block + } + ``` +* **Alert Location:** On the root `azurerm_recovery_services_vault` resource. + +## Involved Resource + +* `azurerm_recovery_services_vault` + +## Solution + +To resolve this finding, you must enable a managed identity on the Vault and configure the `encryption` block by mandatorily providing the `key_id` from Azure Key Vault. + +```terraform +resource "azurerm_recovery_services_vault" "secure_vault" { + name = "secure-recovery-vault" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + sku = "Standard" + + # 1. Enable identity for Key Vault access + identity { + type = "SystemAssigned" + } + + # 2. Configure CMK encryption (key_id is required in this block) + encryption { + key_id = azurerm_key_vault_key.example.id + use_system_assigned_identity = true + } +} diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego index 05df1852299..bfba3322f73 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: El bloque de encriptación no está definido. +# RULE 1: The encryption block is not defined. CxPolicy[result] { doc := input.document[i] vault := doc.resource.azurerm_recovery_services_vault[name] diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/README.md b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/README.md index 59e612fbeec..bf17023f60d 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/README.md +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/README.md @@ -1,72 +1,72 @@ -# Regla KICS: Recovery Services Vault Cross Region Restore Disabled - -## Descripción General - -Esta regla de KICS verifica que la funcionalidad de **Restauración entre Regiones** (`cross_region_restore_enabled`) esté habilitada en los almacenes de **Recovery Services Vault**. - -Habilitar la Restauración entre Regiones (CRR) es un componente crítico de una estrategia de continuidad de negocio y recuperación ante desastres (DRP). Esta característica permite realizar restauraciones de datos en una región secundaria emparejada de Azure en cualquier momento, garantizando el acceso a los backups incluso si la región principal sufre una interrupción total o desastre regional. - -**Nota técnica:** Para que la restauración entre regiones sea efectiva, el almacén debe tener configurado el tipo de almacenamiento como `GeoRedundant`. - -## Lógica de la Regla - -La política analiza el recurso `azurerm_recovery_services_vault` evaluando dos condiciones: -1. **Atributo Ausente:** Si no se define explícitamente `cross_region_restore_enabled`, se considera no conforme, ya que la configuración por defecto no garantiza la disponibilidad del dato en la región secundaria. -2. **Configuración Incorrecta:** Si el atributo se establece explícitamente como `false`, se genera una alerta indicando la falta de redundancia operativa para restauraciones. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Configuración de CRR Ausente - -* **Descripción:** El almacén se define sin especificar la política de restauración regional, lo que resulta en la desactivación por defecto de esta medida de resiliencia. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_recovery_services_vault" "fail_missing" { - name = "vault-insecure" - location = "West Europe" - resource_group_name = azurerm_resource_group.example.name - sku = "Standard" - storage_mode_type = "GeoRedundant" - # Falta cross_region_restore_enabled = true - } - ``` -* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_recovery_services_vault`. - ---- - -### Caso 2: CRR Deshabilitado Explícitamente - -* **Descripción:** Se ha configurado el atributo `cross_region_restore_enabled` con el valor `false`, impidiendo la recuperación de desastres en regiones emparejadas. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_recovery_services_vault" "fail_false" { - name = "vault-disabled" - storage_mode_type = "GeoRedundant" - cross_region_restore_enabled = false # <-- Problema detectado - } - ``` -* **Ubicación de la Alerta:** Atributo `cross_region_restore_enabled`. - -## Recurso Involucrado - -* `azurerm_recovery_services_vault` - -## Solución - -Establezca `cross_region_restore_enabled` en `true` y asegúrese de que el `storage_mode_type` sea `GeoRedundant`. - -```terraform -resource "azurerm_recovery_services_vault" "secure_vault" { - name = "vault-resilient" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - sku = "Standard" - storage_mode_type = "GeoRedundant" - - # SOLUCIÓN: Habilitar restauración entre regiones - cross_region_restore_enabled = true -} \ No newline at end of file +# KICS Rule: Recovery Services Vault Cross Region Restore Disabled + +## General Description + +This KICS rule verifies that the **Cross Region Restore** functionality (`cross_region_restore_enabled`) is enabled in **Recovery Services Vault** vaults. + +Enabling Cross Region Restore (CRR) is a critical component of a business continuity and disaster recovery strategy (DRP). This feature allows data restores to be performed in a secondary paired Azure region at any time, ensuring access to backups even if the primary region suffers a total outage or regional disaster. + +**Technical note:** For cross-region restore to be effective, the vault must have its storage type configured as `GeoRedundant`. + +## Rule Logic + +The policy analyzes the `azurerm_recovery_services_vault` resource by evaluating two conditions: +1. **Missing Attribute:** If `cross_region_restore_enabled` is not explicitly defined, it is considered non-compliant, since the default configuration does not guarantee data availability in the secondary region. +2. **Incorrect Configuration:** If the attribute is explicitly set to `false`, an alert is generated indicating the lack of operational redundancy for restores. + +## Detected Failure Cases + +The following describes the scenarios that this policy will detect. + +--- + +### Case 1: Missing CRR Configuration + +* **Description:** The vault is defined without specifying the regional restore policy, resulting in the default deactivation of this resilience measure. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_recovery_services_vault" "fail_missing" { + name = "vault-insecure" + location = "West Europe" + resource_group_name = azurerm_resource_group.example.name + sku = "Standard" + storage_mode_type = "GeoRedundant" + # Missing cross_region_restore_enabled = true + } + ``` +* **Alert Location:** On the root `azurerm_recovery_services_vault` resource. + +--- + +### Case 2: CRR Explicitly Disabled + +* **Description:** The `cross_region_restore_enabled` attribute has been configured with the value `false`, preventing disaster recovery in paired regions. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_recovery_services_vault" "fail_false" { + name = "vault-disabled" + storage_mode_type = "GeoRedundant" + cross_region_restore_enabled = false # <-- Detected issue + } + ``` +* **Alert Location:** `cross_region_restore_enabled` attribute. + +## Involved Resource + +* `azurerm_recovery_services_vault` + +## Solution + +Set `cross_region_restore_enabled` to `true` and ensure that `storage_mode_type` is `GeoRedundant`. + +```terraform +resource "azurerm_recovery_services_vault" "secure_vault" { + name = "vault-resilient" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + sku = "Standard" + storage_mode_type = "GeoRedundant" + + # SOLUTION: Enable cross-region restore + cross_region_restore_enabled = true +} diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego index e07bf3e96bf..de7299118c7 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: Atributo 'cross_region_restore_enabled' ausente. +# RULE 1: The 'cross_region_restore_enabled' attribute is missing. CxPolicy[result] { doc := input.document[i] vault := doc.resource.azurerm_recovery_services_vault[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: Atributo 'cross_region_restore_enabled' establecido en false. +# RULE 2: The 'cross_region_restore_enabled' attribute is set to false. CxPolicy[result] { doc := input.document[i] vault := doc.resource.azurerm_recovery_services_vault[name] diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/README.md index bed1a30d845..1958a059a80 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/README.md +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/README.md @@ -1,79 +1,79 @@ -# Regla KICS: Recovery Services Vault Infrastructure Encryption Disabled - -## Descripción General - -Esta regla de KICS verifica que el **Cifrado de Infraestructura** (`infrastructure_encryption_enabled`) esté habilitado en los almacenes de **Recovery Services Vault**. - -El cifrado de infraestructura proporciona una capa adicional de protección mediante el uso de un segundo algoritmo de cifrado (**Double Encryption**). Mientras que todos los datos en Azure ya están cifrados en reposo, habilitar esta opción asegura que los datos se cifren dos veces utilizando dos algoritmos independientes. Esta configuración es fundamental para organizaciones con requisitos de cumplimiento altamente estrictos que buscan mitigar riesgos ante posibles vulnerabilidades en un único estándar criptográfico. - -## Lógica de la Regla - -La política analiza el recurso `azurerm_recovery_services_vault` validando dos aspectos técnicos: -1. **Bloque de Cifrado:** Verifica la existencia del bloque `encryption`. Si no existe, se asume que no hay doble cifrado. -2. **Cifrado de Infraestructura:** Verifica que el atributo `infrastructure_encryption_enabled` esté explícitamente establecido en `true`. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Bloque de Cifrado Ausente - -* **Descripción:** El almacén no tiene definido el bloque `encryption`, por lo que utiliza únicamente el cifrado predeterminado de Azure sin capas adicionales. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_recovery_services_vault" "fail_missing" { - name = "insecure-vault" - resource_group_name = "rg-prod" - location = "West Europe" - sku = "Standard" - # Falta bloque encryption {} - } - ``` -* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_recovery_services_vault`. - ---- - -### Caso 2: Cifrado de Infraestructura Deshabilitado - -* **Descripción:** El bloque `encryption` existe pero el atributo `infrastructure_encryption_enabled` no está configurado o se encuentra en `false`. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_recovery_services_vault" "fail_disabled" { - name = "vault-vulnerable" - # ... - encryption { - key_id = azurerm_key_vault_key.example.id - infrastructure_encryption_enabled = false - use_system_assigned_identity = true - } - } - ``` -* **Ubicación de la Alerta:** Atributo `infrastructure_encryption_enabled`. - -## Recurso Involucrado - -* `azurerm_recovery_services_vault` - -## Solución - -Para mitigar este riesgo, asegúrese de declarar el bloque `encryption` estableciendo `infrastructure_encryption_enabled` en `true`. - -```terraform -resource "azurerm_recovery_services_vault" "secure_vault" { - name = "secure-recovery-vault" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - sku = "Standard" - - identity { - type = "SystemAssigned" - } - - encryption { - key_id = azurerm_key_vault_key.example.id - infrastructure_encryption_enabled = true - use_system_assigned_identity = true - } -} \ No newline at end of file +# KICS Rule: Recovery Services Vault Infrastructure Encryption Disabled + +## General Description + +This KICS rule verifies that **Infrastructure Encryption** (`infrastructure_encryption_enabled`) is enabled in **Recovery Services Vault** vaults. + +Infrastructure encryption provides an additional layer of protection through the use of a second encryption algorithm (**Double Encryption**). While all data in Azure is already encrypted at rest, enabling this option ensures that data is encrypted twice using two independent algorithms. This configuration is essential for organizations with highly strict compliance requirements seeking to mitigate risks against potential vulnerabilities in a single cryptographic standard. + +## Rule Logic + +The policy analyzes the `azurerm_recovery_services_vault` resource by validating two technical aspects: +1. **Encryption Block:** Verifies the existence of the `encryption` block. If it does not exist, it is assumed that there is no double encryption. +2. **Infrastructure Encryption:** Verifies that the `infrastructure_encryption_enabled` attribute is explicitly set to `true`. + +## Detected Failure Cases + +The following describes the scenarios that this policy will detect. + +--- + +### Case 1: Missing Encryption Block + +* **Description:** The vault does not have the `encryption` block defined, so it uses only Azure's default encryption without additional layers. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_recovery_services_vault" "fail_missing" { + name = "insecure-vault" + resource_group_name = "rg-prod" + location = "West Europe" + sku = "Standard" + # Missing encryption {} block + } + ``` +* **Alert Location:** On the root `azurerm_recovery_services_vault` resource. + +--- + +### Case 2: Infrastructure Encryption Disabled + +* **Description:** The `encryption` block exists but the `infrastructure_encryption_enabled` attribute is not configured or is set to `false`. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_recovery_services_vault" "fail_disabled" { + name = "vault-vulnerable" + # ... + encryption { + key_id = azurerm_key_vault_key.example.id + infrastructure_encryption_enabled = false + use_system_assigned_identity = true + } + } + ``` +* **Alert Location:** `infrastructure_encryption_enabled` attribute. + +## Involved Resource + +* `azurerm_recovery_services_vault` + +## Solution + +To mitigate this risk, ensure you declare the `encryption` block setting `infrastructure_encryption_enabled` to `true`. + +```terraform +resource "azurerm_recovery_services_vault" "secure_vault" { + name = "secure-recovery-vault" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + sku = "Standard" + + identity { + type = "SystemAssigned" + } + + encryption { + key_id = azurerm_key_vault_key.example.id + infrastructure_encryption_enabled = true + use_system_assigned_identity = true + } +} diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego index 198780181f1..9472a676075 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: El bloque 'encryption' no está definido. +# RULE 1: The 'encryption' block is not defined. CxPolicy[result] { doc := input.document[i] vault := doc.resource.azurerm_recovery_services_vault[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: El atributo 'infrastructure_encryption_enabled' no está en true. +# RULE 2: The 'infrastructure_encryption_enabled' attribute is not set to true. CxPolicy[result] { doc := input.document[i] vault := doc.resource.azurerm_recovery_services_vault[name] diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/README.md b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/README.md index d243e68a8e5..ee4292a68dd 100644 --- a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/README.md +++ b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/README.md @@ -1,56 +1,56 @@ -# Regla KICS: SQL Server TDE Not Encrypted with CMK - -## Descripción General - -Esta regla de KICS asegura que la característica **Transparent Data Encryption (TDE)** de Azure SQL Server esté configurada para utilizar una **clave gestionada por el cliente (Customer-Managed Key - CMK)** almacenada en Azure Key Vault. - -Por defecto, Azure SQL cifra los datos en reposo utilizando una clave gestionada por el servicio (Microsoft). Aunque este método proporciona seguridad base, el uso de CMK ofrece un nivel de control superior indispensable para cumplir con normativas estrictas de seguridad corporativa. Con CMK, la organización asume el control total sobre el ciclo de vida de las claves, permitiendo la rotación, revocación de acceso y auditoría de uso de forma soberana a través de Azure Key Vault. - -## Lógica de la Regla - -La política audita la configuración de Terraform siguiendo estos criterios: -1. **Identificación:** Localiza todos los recursos de tipo `azurerm_mssql_server`. -2. **Vinculación:** Busca si existe un recurso independiente del tipo `azurerm_mssql_server_transparent_data_encryption` vinculado al servidor mediante el atributo `server_id`. -3. **Validación de Clave:** Verifica que dicho recurso tenga definido explícitamente el atributo `key_vault_key_id`. -4. **Alerta:** Si no se encuentra el recurso de cifrado o si falta la referencia a la clave de Key Vault, se genera un hallazgo. - -## Caso de Fallo Detectado - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso Único: Uso de Clave Gestionada por el Servicio (Default) - -* **Descripción:** Se define el servidor SQL pero no se añade el recurso adicional necesario para habilitar el cifrado TDE mediante llaves del cliente, manteniendo el cifrado por defecto de Azure. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_mssql_server" "fail_server" { - name = "insecure-sql-server" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - version = "12.0" - administrator_login = "sqladmin" - administrator_password = "P@ssword123!" - - # Falta el recurso azurerm_mssql_server_transparent_data_encryption - } - ``` -* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_mssql_server`. - -## Recursos Involucrados - -* `azurerm_mssql_server` -* `azurerm_mssql_server_transparent_data_encryption` - -## Solución - -Para mitigar este riesgo, cree un recurso `azurerm_mssql_server_transparent_data_encryption`, vincúlelo al servidor SQL y proporcione la URI de la clave de Azure Key Vault. - -```terraform -resource "azurerm_mssql_server_transparent_data_encryption" "secure_tde" { - server_id = azurerm_mssql_server.example.id - - # SOLUCIÓN: Usar una clave gestionada por el cliente - key_vault_key_id = azurerm_key_vault_key.example.id -} \ No newline at end of file +# KICS Rule: SQL Server TDE Not Encrypted with CMK + +## General Description + +This KICS rule ensures that the **Transparent Data Encryption (TDE)** feature of Azure SQL Server is configured to use a **Customer-Managed Key (CMK)** stored in Azure Key Vault. + +By default, Azure SQL encrypts data at rest using a service-managed key (Microsoft). Although this method provides baseline security, using CMK offers a superior level of control that is indispensable for meeting strict corporate security regulations. With CMK, the organization assumes full control over the key lifecycle, allowing rotation, access revocation, and usage auditing in a sovereign manner through Azure Key Vault. + +## Rule Logic + +The policy audits the Terraform configuration following these criteria: +1. **Identification:** Locates all resources of type `azurerm_mssql_server`. +2. **Linking:** Checks whether an independent resource of type `azurerm_mssql_server_transparent_data_encryption` exists linked to the server via the `server_id` attribute. +3. **Key Validation:** Verifies that said resource has the `key_vault_key_id` attribute explicitly defined. +4. **Alert:** If the encryption resource is not found or if the Key Vault key reference is missing, a finding is generated. + +## Detected Failure Case + +The following describes the scenario this policy will detect. + +--- + +### Single Case: Use of Service-Managed Key (Default) + +* **Description:** The SQL server is defined but the additional resource required to enable TDE encryption using customer keys is not added, maintaining Azure's default encryption. +* **Example of Problematic Terraform Code:** + ```terraform + resource "azurerm_mssql_server" "fail_server" { + name = "insecure-sql-server" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + version = "12.0" + administrator_login = "sqladmin" + administrator_password = "P@ssword123!" + + # Missing azurerm_mssql_server_transparent_data_encryption resource + } + ``` +* **Alert Location:** On the root `azurerm_mssql_server` resource. + +## Involved Resources + +* `azurerm_mssql_server` +* `azurerm_mssql_server_transparent_data_encryption` + +## Solution + +To mitigate this risk, create an `azurerm_mssql_server_transparent_data_encryption` resource, link it to the SQL server, and provide the Azure Key Vault key URI. + +```terraform +resource "azurerm_mssql_server_transparent_data_encryption" "secure_tde" { + server_id = azurerm_mssql_server.example.id + + # SOLUTION: Use a customer-managed key + key_vault_key_id = azurerm_key_vault_key.example.id +} diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego index 224c2f7dd51..519e0fc388d 100644 --- a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego @@ -16,7 +16,7 @@ check_id(current, target) { current == sprintf("${%s}", [target]) } -# REGLA 1: SQL Server sin configuración de TDE explícita o sin CMK. +# RULE 1: SQL Server without explicit TDE configuration or without CMK. CxPolicy[result] { doc := input.document[i] server := doc.resource.azurerm_mssql_server[name] diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/README.md b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/README.md index 6dfd2710310..67b9e724aa9 100644 --- a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/README.md +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/README.md @@ -1,55 +1,55 @@ -# Regla KICS: Storage Account Geo-Redundancy Disabled - -## Descripción General - -Esta regla de KICS verifica que las cuentas de almacenamiento de Azure (`azurerm_storage_account`) estén configuradas con **Redundancia Geográfica**. - -La redundancia geográfica es una estrategia de continuidad del negocio fundamental. Al habilitarla, Azure copia los datos de forma asíncrona en una región secundaria situada a cientos de kilómetros de la región principal. Esto garantiza que, ante un desastre regional catastrófico (fallos masivos de red, desastres naturales o cortes de energía en toda una región), los datos permanezcan duraderos y disponibles para su recuperación, minimizando el RPO (objetivo de punto de recuperación) y el RTO (objetivo de tiempo de recuperación). - -## Lógica de la Regla - -La política audita el atributo `account_replication_type` del recurso `azurerm_storage_account`: -1. **Validación de Tipo:** Comprueba si el valor configurado pertenece al grupo de alta disponibilidad regional: `GRS`, `RAGRS`, `GZRS` o `RAGZRS`. -2. **Detección de Riesgo:** Si el valor es `LRS` (Localmente redundante) o `ZRS` (Redundancia de zona), se genera una alerta, ya que estos niveles solo protegen contra fallos de hardware dentro de un centro de datos o zona, pero no contra la pérdida de una región completa. - -## Caso de Fallo Detectado - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso Único: Replicación Local o Zonal (LRS/ZRS) - -* **Descripción:** La cuenta de almacenamiento utiliza un esquema de replicación que no se extiende fuera de la región principal, dejando los datos vulnerables ante desastres regionales. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_storage_account" "fail_storage" { - name = "insecurestorage" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - - # FALLO: Replicación limitada a la región local - account_replication_type = "LRS" - } - ``` -* **Ubicación de la Alerta:** Atributo `account_replication_type`. - -## Recurso Involucrado - -* `azurerm_storage_account` - -## Solución - -Para mitigar este riesgo en entornos de producción, cambie el tipo de replicación a uno que soporte redundancia geográfica, como **GRS**. - -```terraform -resource "azurerm_storage_account" "secure_storage" { - name = "securestorage" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - - # SOLUCIÓN: Habilitar redundancia geográfica - account_replication_type = "GRS" -} \ No newline at end of file +# KICS Rule: Storage Account Geo-Redundancy Disabled + +## General Description + +This KICS rule verifies that Azure storage accounts (`azurerm_storage_account`) are configured with **Geo-Redundancy**. + +Geo-redundancy is a fundamental business continuity strategy. By enabling it, Azure asynchronously copies data to a secondary region located hundreds of kilometers from the primary region. This ensures that, in the event of a catastrophic regional disaster (massive network failures, natural disasters, or region-wide power outages), data remains durable and available for recovery, minimizing RPO (Recovery Point Objective) and RTO (Recovery Time Objective). + +## Rule Logic + +The policy audits the `account_replication_type` attribute of the `azurerm_storage_account` resource: +1. **Type Validation:** Checks whether the configured value belongs to the high regional availability group: `GRS`, `RAGRS`, `GZRS`, or `RAGZRS`. +2. **Risk Detection:** If the value is `LRS` (Locally Redundant) or `ZRS` (Zone Redundant), an alert is generated, as these levels only protect against hardware failures within a datacenter or zone, but not against the loss of an entire region. + +## Detected Failure Case + +The following describes the scenario that this policy will detect. + +--- + +### Single Case: Local or Zonal Replication (LRS/ZRS) + +* **Description:** The storage account uses a replication scheme that does not extend beyond the primary region, leaving data vulnerable to regional disasters. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_storage_account" "fail_storage" { + name = "insecurestorage" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + + # FAILURE: Replication limited to the local region + account_replication_type = "LRS" + } + ``` +* **Alert Location:** `account_replication_type` attribute. + +## Involved Resource + +* `azurerm_storage_account` + +## Solution + +To mitigate this risk in production environments, change the replication type to one that supports geo-redundancy, such as **GRS**. + +```terraform +resource "azurerm_storage_account" "secure_storage" { + name = "securestorage" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + + # SOLUTION: Enable geo-redundancy + account_replication_type = "GRS" +} diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego index e6ab72bdac2..04c75160959 100644 --- a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego @@ -4,7 +4,7 @@ import data.generic.terraform as tf_lib geo_redundant_types := {"GRS", "RAGRS", "GZRS", "RAGZRS"} -# REGLA 1: El tipo de replicación no es Geo-Redundante (ej. es LRS o ZRS). +# RULE 1: The replication type is not Geo-Redundant (e.g., it is LRS or ZRS). CxPolicy[result] { doc := input.document[i] sa := doc.resource.azurerm_storage_account[name] diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/README.md index 5bc305813ee..d4240c2310f 100644 --- a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/README.md +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/README.md @@ -1,72 +1,72 @@ -# Regla KICS: Storage Account Infrastructure Encryption Disabled - -## Descripción General - -Esta regla de KICS verifica que el **Cifrado de Infraestructura** (`infrastructure_encryption_enabled`) esté habilitado en los recursos `azurerm_storage_account`. - -Por defecto, Azure Storage cifra todos los datos en reposo mediante el cifrado del lado del servidor (SSE) utilizando claves gestionadas por Microsoft. Sin embargo, habilitar el cifrado de infraestructura proporciona una capa de defensa en profundidad conocida como **Doble Cifrado** (Double Encryption). En este modelo, los datos se cifran dos veces: una a nivel del servicio de almacenamiento y otra a nivel de la infraestructura subyacente, utilizando dos algoritmos de cifrado independientes y claves distintas. Esto protege la información incluso en el caso improbable de que un algoritmo o clave individual se vea comprometido. - -**Nota técnica:** Esta configuración es **inmutable**. Solo se puede habilitar en el momento de la creación de la cuenta de almacenamiento; no es posible activarla posteriormente sin recrear el recurso. - -## Lógica de la Regla - -La política audita el recurso `azurerm_storage_account` evaluando dos escenarios: -1. **Atributo Ausente:** Si no se define explícitamente `infrastructure_encryption_enabled`, KICS asume el valor por defecto (`false`) y genera una alerta sobre el recurso. -2. **Deshabilitado Explícitamente:** Si el atributo está configurado como `false`, se genera una alerta indicando que la protección de doble cifrado no está activa. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Configuración de Doble Cifrado Ausente - -* **Descripción:** Se define la cuenta de almacenamiento sin incluir el parámetro de cifrado de infraestructura, delegando la seguridad únicamente al cifrado simple predeterminado. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_storage_account" "fail_missing" { - name = "storageinsecure" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "LRS" - # Falta infrastructure_encryption_enabled = true - } - ``` -* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_storage_account`. - ---- - -### Caso 2: Cifrado de Infraestructura Deshabilitado Explícitamente - -* **Descripción:** El atributo `infrastructure_encryption_enabled` se ha configurado como `false`, desactivando la capa de seguridad adicional requerida. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_storage_account" "fail_explicit" { - name = "storagedisabled" - # ... - infrastructure_encryption_enabled = false # <-- Problema detectado - } - ``` -* **Ubicación de la Alerta:** Atributo `infrastructure_encryption_enabled`. - -## Recurso Involucrado - -* `azurerm_storage_account` - -## Solución - -Para mitigar este riesgo, establezca `infrastructure_encryption_enabled` en `true` durante la definición inicial de la cuenta de almacenamiento. - -```terraform -resource "azurerm_storage_account" "secure_storage" { - name = "storage-secure" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "GRS" - - # SOLUCIÓN: Habilitar el doble cifrado de infraestructura - infrastructure_encryption_enabled = true -} \ No newline at end of file +# KICS Rule: Storage Account Infrastructure Encryption Disabled + +## General Description + +This KICS rule verifies that **Infrastructure Encryption** (`infrastructure_encryption_enabled`) is enabled on `azurerm_storage_account` resources. + +By default, Azure Storage encrypts all data at rest using server-side encryption (SSE) with Microsoft-managed keys. However, enabling infrastructure encryption provides a defense-in-depth layer known as **Double Encryption**. In this model, data is encrypted twice: once at the storage service level and once at the underlying infrastructure level, using two independent encryption algorithms and distinct keys. This protects information even in the unlikely event that a single algorithm or key is compromised. + +**Technical note:** This setting is **immutable**. It can only be enabled at the time of storage account creation; it cannot be activated afterwards without recreating the resource. + +## Rule Logic + +The policy audits the `azurerm_storage_account` resource by evaluating two scenarios: +1. **Missing Attribute:** If `infrastructure_encryption_enabled` is not explicitly defined, KICS assumes the default value (`false`) and generates an alert on the resource. +2. **Explicitly Disabled:** If the attribute is configured as `false`, an alert is generated indicating that double encryption protection is not active. + +## Detected Failure Cases + +The following describes the scenarios that this policy will detect. + +--- + +### Case 1: Missing Double Encryption Configuration + +* **Description:** The storage account is defined without including the infrastructure encryption parameter, delegating security solely to the default single encryption. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_storage_account" "fail_missing" { + name = "storageinsecure" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "LRS" + # Missing infrastructure_encryption_enabled = true + } + ``` +* **Alert Location:** On the root `azurerm_storage_account` resource. + +--- + +### Case 2: Infrastructure Encryption Explicitly Disabled + +* **Description:** The `infrastructure_encryption_enabled` attribute has been configured as `false`, disabling the required additional security layer. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_storage_account" "fail_explicit" { + name = "storagedisabled" + # ... + infrastructure_encryption_enabled = false # <-- Detected issue + } + ``` +* **Alert Location:** `infrastructure_encryption_enabled` attribute. + +## Involved Resource + +* `azurerm_storage_account` + +## Solution + +To mitigate this risk, set `infrastructure_encryption_enabled` to `true` during the initial definition of the storage account. + +```terraform +resource "azurerm_storage_account" "secure_storage" { + name = "storage-secure" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "GRS" + + # SOLUTION: Enable infrastructure double encryption + infrastructure_encryption_enabled = true +} diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego index cc2460acdb6..46e82f114ad 100644 --- a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: Atributo 'infrastructure_encryption_enabled' ausente. +# RULE 1: The 'infrastructure_encryption_enabled' attribute is missing. CxPolicy[result] { doc := input.document[i] sa := doc.resource.azurerm_storage_account[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: Atributo 'infrastructure_encryption_enabled' establecido en false. +# RULE 2: The 'infrastructure_encryption_enabled' attribute is set to false. CxPolicy[result] { doc := input.document[i] sa := doc.resource.azurerm_storage_account[name] diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/README.md b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/README.md index bf0b5dab876..ccc9dec05ce 100644 --- a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/README.md +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/README.md @@ -1,63 +1,63 @@ -# Regla KICS: Storage Account ReadOnly Lock Missing - -## Descripción General - -Esta regla de KICS verifica que las cuentas de almacenamiento de Azure (`azurerm_storage_account`) tengan aplicado un **bloqueo de recursos** (`azurerm_management_lock`) configurado específicamente en el nivel **`ReadOnly`**. - -Los bloqueos de Azure Resource Manager (ARM) proporcionan una capa de seguridad adicional que trasciende los permisos de RBAC. Aplicar un bloqueo de tipo `ReadOnly` a una cuenta de almacenamiento garantiza que la configuración del recurso (como las reglas de firewall, los niveles de acceso o la configuración de replicación) no pueda ser modificada ni el recurso eliminado accidentalmente, incluso por administradores. Es una práctica esencial para activos de datos críticos en entornos de producción. - -## Lógica de la Regla - -La política realiza un análisis cruzado entre los recursos de la cuenta de almacenamiento y los bloqueos definidos: -1. **Identificación:** Localiza todas las instancias de `azurerm_storage_account`. -2. **Vinculación:** Busca recursos `azurerm_management_lock` cuyo atributo `scope` referencie al ID del Storage Account. -3. **Validación de Nivel:** Verifica que el atributo `lock_level` sea estrictamente `"ReadOnly"`. -4. **Generación de Hallazgo:** Si el recurso no tiene ningún bloqueo o si los bloqueos existentes tienen un nivel inferior (como `CanNotDelete`), se genera una alerta. - -## Casos de Fallo Detectados - -### Caso 1: Storage Account sin Bloqueo - -* **Descripción:** La cuenta de almacenamiento se ha desplegado sin ninguna restricción de gestión, permitiendo modificaciones accidentales. -* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_storage_account`. - ---- - -### Caso 2: Bloqueo con Nivel Incorrecto - -* **Descripción:** Existe un bloqueo asociado al recurso, pero su nivel es `"CanNotDelete"`, lo cual permite modificaciones en la configuración que la regla busca restringir mediante `"ReadOnly"`. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_management_lock" "fail_lock" { - name = "prevent-deletion" - scope = azurerm_storage_account.example.id - lock_level = "CanNotDelete" # <-- FALLO: Se requiere 'ReadOnly' - } - ``` -* **Ubicación de la Alerta:** Atributo `lock_level` del recurso de bloqueo. - -## Recursos Involucrados - -* `azurerm_storage_account` -* `azurerm_management_lock` - -## Solución - -Añada un recurso `azurerm_management_lock` apuntando al ID de la cuenta de almacenamiento con el nivel `ReadOnly`. - -```terraform -resource "azurerm_storage_account" "secure_sa" { - name = "storage-prod-critical" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "GRS" -} - -# SOLUCIÓN: Aplicar bloqueo ReadOnly -resource "azurerm_management_lock" "sa_readonly_lock" { - name = "critical-storage-lock" - scope = azurerm_storage_account.secure_sa.id - lock_level = "ReadOnly" - notes = "Bloqueo de seguridad para cumplimiento de política de gobernanza" -} \ No newline at end of file +# KICS Rule: Storage Account ReadOnly Lock Missing + +## General Description + +This KICS rule verifies that Azure storage accounts (`azurerm_storage_account`) have a **resource lock** (`azurerm_management_lock`) applied, specifically configured at the **`ReadOnly`** level. + +Azure Resource Manager (ARM) locks provide an additional security layer that transcends RBAC permissions. Applying a `ReadOnly` type lock to a storage account ensures that the resource configuration (such as firewall rules, access tiers, or replication settings) cannot be modified or the resource accidentally deleted, even by administrators. It is an essential practice for critical data assets in production environments. + +## Rule Logic + +The policy performs a cross-analysis between storage account resources and defined locks: +1. **Identification:** Locates all instances of `azurerm_storage_account`. +2. **Linking:** Searches for `azurerm_management_lock` resources whose `scope` attribute references the Storage Account ID. +3. **Level Validation:** Verifies that the `lock_level` attribute is strictly `"ReadOnly"`. +4. **Finding Generation:** If the resource has no lock, or if existing locks have a lower level (such as `CanNotDelete`), an alert is generated. + +## Detected Failure Cases + +### Case 1: Storage Account Without a Lock + +* **Description:** The storage account has been deployed without any management restriction, allowing accidental modifications. +* **Alert Location:** On the root `azurerm_storage_account` resource. + +--- + +### Case 2: Lock With Incorrect Level + +* **Description:** A lock associated with the resource exists, but its level is `"CanNotDelete"`, which allows modifications to the configuration that this rule seeks to restrict via `"ReadOnly"`. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_management_lock" "fail_lock" { + name = "prevent-deletion" + scope = azurerm_storage_account.example.id + lock_level = "CanNotDelete" # <-- FAILURE: 'ReadOnly' is required + } + ``` +* **Alert Location:** `lock_level` attribute of the lock resource. + +## Involved Resources + +* `azurerm_storage_account` +* `azurerm_management_lock` + +## Solution + +Add an `azurerm_management_lock` resource pointing to the storage account ID with the `ReadOnly` level. + +```terraform +resource "azurerm_storage_account" "secure_sa" { + name = "storage-prod-critical" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "GRS" +} + +# SOLUTION: Apply ReadOnly lock +resource "azurerm_management_lock" "sa_readonly_lock" { + name = "critical-storage-lock" + scope = azurerm_storage_account.secure_sa.id + lock_level = "ReadOnly" + notes = "Security lock for governance policy compliance" +} diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego index 3b454baa130..addf9d7041b 100644 --- a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego @@ -16,7 +16,7 @@ check_lock_scope(current, target) { current == sprintf("${%s}", [target]) } -# CASO 1: Storage Account totalmente desprotegido (sin bloqueos asociados) +# CASE 1: Storage Account completely unprotected (no associated locks) CxPolicy[result] { doc := input.document[i] sa := doc.resource.azurerm_storage_account[sa_name] @@ -39,7 +39,7 @@ CxPolicy[result] { } } -# CASO 2: Storage Account con bloqueo incorrecto (nivel distinto a ReadOnly) +# CASE 2: Storage Account with incorrect lock (level other than ReadOnly) CxPolicy[result] { doc := input.document[i] lock := doc.resource.azurerm_management_lock[lock_name] diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/README.md b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/README.md index 9b9b41c70e4..d786deae52f 100644 --- a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/README.md +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/README.md @@ -1,76 +1,76 @@ -# Regla KICS: Storage Account Blob Versioning Disabled - -## Descripción General - -Esta regla verifica que la característica de **Versioning** (control de versiones) esté habilitada en los recursos `azurerm_storage_account`. - -El control de versiones de Blobs permite mantener automáticamente versiones anteriores de un objeto cuando este se modifica o elimina. Es una capa de protección fundamental para escenarios de recuperación de datos ante errores humanos, sobreescrituras accidentales o ataques de ransomware, permitiendo restaurar un estado anterior del archivo sin necesidad de recurrir a copias de seguridad externas complejas. - -## Lógica de la Regla - -La política evalúa la configuración en tres niveles de granularidad: -1. **Bloque Ausente:** Si el recurso no tiene definido el bloque `blob_properties`. -2. **Atributo Ausente:** Si existe el bloque pero no se define el parámetro `versioning_enabled`. -3. **Valor Incorrecto:** Si `versioning_enabled` se ha configurado explícitamente como `false`. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Configuración de Bloque Ausente - -* **Descripción:** El recurso no define el bloque `blob_properties`. Por defecto, Azure deshabilita el versionado si no se especifica. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_storage_account" "fail_1" { - name = "storage-insecure-1" - resource_group_name = "rg-prod" - location = "West Europe" - account_tier = "Standard" - account_replication_type = "LRS" - - # El bloque blob_properties es inexistente - } - ``` -* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_storage_account`. - ---- - -### Caso 2: Versionado Deshabilitado Explícitamente - -* **Descripción:** Se ha incluido el bloque de propiedades pero el versionado está apagado, lo que impide la recuperación de archivos modificados. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_storage_account" "fail_2" { - name = "storage-insecure-2" - # ... - blob_properties { - versioning_enabled = false # <-- PROBLEMA: Deshabilitado. - } - } - ``` -* **Ubicación de la Alerta:** Línea `versioning_enabled = false`. - -## Recurso Involucrado - -* `azurerm_storage_account` - -## Solución - -Para solucionar este riesgo, asegúrese de incluir el bloque `blob_properties` con el atributo `versioning_enabled` establecido en `true`. - -```terraform -resource "azurerm_storage_account" "secure_storage" { - name = "storage-secure" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "GRS" - - # SOLUCIÓN: Habilitar el control de versiones de blobs - blob_properties { - versioning_enabled = true - } -} \ No newline at end of file +# KICS Rule: Storage Account Blob Versioning Disabled + +## General Description + +This rule verifies that the **Versioning** feature (version control) is enabled on `azurerm_storage_account` resources. + +Blob versioning allows automatically maintaining previous versions of an object when it is modified or deleted. It is a fundamental protection layer for data recovery scenarios involving human errors, accidental overwrites, or ransomware attacks, allowing restoration of a previous state of the file without needing to resort to complex external backups. + +## Rule Logic + +The policy evaluates the configuration at three levels of granularity: +1. **Missing Block:** If the resource does not have the `blob_properties` block defined. +2. **Missing Attribute:** If the block exists but the `versioning_enabled` parameter is not defined. +3. **Incorrect Value:** If `versioning_enabled` has been explicitly configured as `false`. + +## Detected Failure Cases + +The following describes the scenarios that this policy will detect. + +--- + +### Case 1: Missing Block Configuration + +* **Description:** The resource does not define the `blob_properties` block. By default, Azure disables versioning if not specified. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_storage_account" "fail_1" { + name = "storage-insecure-1" + resource_group_name = "rg-prod" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" + + # The blob_properties block is missing + } + ``` +* **Alert Location:** On the root `azurerm_storage_account` resource. + +--- + +### Case 2: Versioning Explicitly Disabled + +* **Description:** The properties block is included but versioning is turned off, which prevents recovery of modified files. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_storage_account" "fail_2" { + name = "storage-insecure-2" + # ... + blob_properties { + versioning_enabled = false # <-- ISSUE: Disabled. + } + } + ``` +* **Alert Location:** Line `versioning_enabled = false`. + +## Involved Resource + +* `azurerm_storage_account` + +## Solution + +To resolve this risk, ensure you include the `blob_properties` block with the `versioning_enabled` attribute set to `true`. + +```terraform +resource "azurerm_storage_account" "secure_storage" { + name = "storage-secure" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "GRS" + + # SOLUTION: Enable blob versioning + blob_properties { + versioning_enabled = true + } +} diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego index b46220cd9d7..af6c3e5654f 100644 --- a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# CASO 1: Falta el bloque 'blob_properties' completo. +# CASE 1: The complete 'blob_properties' block is missing. CxPolicy[result] { doc := input.document[i] sa := doc.resource.azurerm_storage_account[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# CASO 2: Existe 'blob_properties' pero falta el atributo 'versioning_enabled'. +# CASE 2: 'blob_properties' exists but the 'versioning_enabled' attribute is missing. CxPolicy[result] { doc := input.document[i] sa := doc.resource.azurerm_storage_account[name] @@ -40,7 +40,7 @@ CxPolicy[result] { } } -# CASO 3: 'versioning_enabled' existe pero está explícitamente a false. +# CASE 3: 'versioning_enabled' exists but is explicitly set to false. CxPolicy[result] { doc := input.document[i] sa := doc.resource.azurerm_storage_account[name] diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/README.md b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/README.md index d239d1dd6b5..af6a1a5da7e 100644 --- a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/README.md +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/README.md @@ -1,46 +1,46 @@ -# Regla KICS: Storage Blob Service Logging Disabled - -## Descripción General - -Esta regla verifica que el registro de diagnóstico (**Diagnostic Settings**) esté habilitado y configurado íntegramente para el servicio de **Blobs** en las cuentas de almacenamiento de Azure. - -Para garantizar una auditoría completa del plano de datos, es imperativo registrar las tres operaciones fundamentales que permiten rastrear el ciclo de vida de los objetos: -* **StorageRead:** Auditoría de lectura de datos de blobs y metadatos de contenedores. -* **StorageWrite:** Auditoría de subidas, creaciones y modificaciones de blobs. -* **StorageDelete:** Auditoría de eliminaciones de objetos y contenedores. - -## Lógica de la Regla - -La política audita el código Terraform evaluando tres niveles de cumplimiento: -1. **Existencia de Recurso:** Verifica que cada `azurerm_storage_account` tenga un recurso `azurerm_monitor_diagnostic_setting` vinculado a su endpoint de blobs (`/blobServices/default`). -2. **Presencia de Logs:** Alerta si el recurso de diagnóstico existe pero no contiene definiciones de registros (`enabled_log`). -3. **Integridad de Categorías:** Analiza que las categorías `StorageRead`, `StorageWrite` y `StorageDelete` estén presentes. Si el conjunto está incompleto, la alerta apunta directamente al bloque `enabled_log`. - -## Casos de Fallo Detectados - -### Caso 1: Servicio de Blobs sin Diagnostic Settings -* **Ubicación:** `azurerm_storage_account`. - -### Caso 2: Diagnostic Setting sin bloques de Log -* **Ubicación:** `azurerm_monitor_diagnostic_setting`. - -### Caso 3: Auditoría de Blobs Incompleta -* **Descripción:** El bloque de registros no contiene el set completo de categorías (Read, Write y Delete). -* **Ubicación:** Bloque `enabled_log` dentro de `azurerm_monitor_diagnostic_setting`. - -## Recursos Involucrados -* `azurerm_storage_account` -* `azurerm_monitor_diagnostic_setting` - -## Solución - -```terraform -resource "azurerm_monitor_diagnostic_setting" "secure_blob_logging" { - name = "blob-audit-complete" - target_resource_id = "${azurerm_storage_account.example.id}/blobServices/default" - storage_account_id = azurerm_storage_account.log_destination.id - - enabled_log { category = "StorageRead" } - enabled_log { category = "StorageWrite" } - enabled_log { category = "StorageDelete" } -} \ No newline at end of file +# KICS Rule: Storage Blob Service Logging Disabled + +## General Description + +This rule verifies that diagnostic logging (**Diagnostic Settings**) is enabled and fully configured for the **Blob** service in Azure storage accounts. + +To ensure complete data plane auditing, it is imperative to log the three fundamental operations that allow tracking the lifecycle of objects: +* **StorageRead:** Audit of blob data reads and container metadata. +* **StorageWrite:** Audit of blob uploads, creations, and modifications. +* **StorageDelete:** Audit of object and container deletions. + +## Rule Logic + +The policy audits the Terraform code by evaluating three compliance levels: +1. **Resource Existence:** Verifies that each `azurerm_storage_account` has an `azurerm_monitor_diagnostic_setting` resource linked to its blob endpoint (`/blobServices/default`). +2. **Log Presence:** Alerts if the diagnostic resource exists but contains no log definitions (`enabled_log`). +3. **Category Integrity:** Analyzes that the `StorageRead`, `StorageWrite`, and `StorageDelete` categories are all present. If the set is incomplete, the alert points directly to the `enabled_log` block. + +## Detected Failure Cases + +### Case 1: Blob Service Without Diagnostic Settings +* **Location:** `azurerm_storage_account`. + +### Case 2: Diagnostic Setting Without Log Blocks +* **Location:** `azurerm_monitor_diagnostic_setting`. + +### Case 3: Incomplete Blob Audit +* **Description:** The log block does not contain the complete set of categories (Read, Write, and Delete). +* **Location:** `enabled_log` block within `azurerm_monitor_diagnostic_setting`. + +## Involved Resources +* `azurerm_storage_account` +* `azurerm_monitor_diagnostic_setting` + +## Solution + +```terraform +resource "azurerm_monitor_diagnostic_setting" "secure_blob_logging" { + name = "blob-audit-complete" + target_resource_id = "${azurerm_storage_account.example.id}/blobServices/default" + storage_account_id = azurerm_storage_account.log_destination.id + + enabled_log { category = "StorageRead" } + enabled_log { category = "StorageWrite" } + enabled_log { category = "StorageDelete" } +} diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego index a8f59e66791..3366b584bd2 100644 --- a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego @@ -14,7 +14,7 @@ is_target_linked(target, sa_name) { contains(target, "blobServices/default") } -# CASO 1: La cuenta de almacenamiento no tiene ningún Diagnostic Setting para Blobs. +# CASE 1: The storage account has no Diagnostic Setting for Blobs. CxPolicy[result] { doc := input.document[i] sa := doc.resource.azurerm_storage_account[name] @@ -37,7 +37,7 @@ diag_exists_for_sa(doc, sa_name) { is_target_linked(diag.target_resource_id, sa_name) } -# CASO 2: El Diagnostic Setting existe pero no tiene ningún bloque 'enabled_log'. +# CASE 2: The Diagnostic Setting exists but has no 'enabled_log' blocks. CxPolicy[result] { doc := input.document[i] diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] @@ -56,7 +56,7 @@ CxPolicy[result] { } } -# CASO 3: El Diagnostic Setting tiene bloques 'enabled_log' pero el conjunto está incompleto. +# CASE 3: The Diagnostic Setting has 'enabled_log' blocks but the set is incomplete. CxPolicy[result] { doc := input.document[i] diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/README.md b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/README.md index c09ad4074f5..6274660fdfd 100644 --- a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/README.md +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/README.md @@ -1,65 +1,65 @@ -# Regla KICS: Storage Immutability Policy Not Locked - -## Descripción General - -Esta regla verifica que las políticas de inmutabilidad (`azurerm_storage_container_immutability_policy`) aplicadas a los contenedores de Azure Storage estén configuradas en estado **Bloqueado** (`locked = true`). - -Las políticas de inmutabilidad permiten que los datos se almacenen en un formato **WORM** (Write Once, Read Many). En el contexto de control de acceso y protección de datos, existen dos estados críticos: -* **Unlocked (Mutable):** La política protege los datos contra borrado o modificación, pero la política en sí puede ser eliminada o modificada por usuarios con altos privilegios. Es un estado transitorio y no garantiza la inalterabilidad a largo plazo. -* **Locked (Inmutable):** Una vez bloqueada, la política se vuelve irreversible; no puede ser eliminada y el periodo de retención solo puede aumentarse. Este estado es un control de integridad estricto que garantiza que ni siquiera un administrador pueda eliminar los datos antes de tiempo. - -## Lógica de la Regla - -La regla audita los recursos `azurerm_storage_container_immutability_policy` evaluando dos condiciones de control: -1. **Omisión del Atributo:** Si no se define el atributo `locked`, Azure asume por defecto el estado "Unlocked", permitiendo que la protección sea removida. -2. **Valor Incorrecto:** Si el atributo `locked` se establece explícitamente en `false`. - -## Casos de Fallo Detectados - -### Caso 1: Atributo de Bloqueo Ausente - -* **Descripción:** Se define una política de retención pero no se especifica si debe estar bloqueada. Por defecto, Azure la crea en estado "Unlocked". -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_storage_container_immutability_policy" "fail_missing" { - storage_container_resource_manager_id = azurerm_storage_container.example.id - retention_period_in_days = 365 - # Falta locked = true - } - ``` -* **Ubicación de la Alerta:** Sobre el recurso raíz `azurerm_storage_container_immutability_policy`. - ---- - -### Caso 2: Política Mutable (Unlocked) - -* **Descripción:** El atributo `locked` se establece explícitamente en `false`, lo que permite que la política de inmutabilidad sea eliminable por usuarios autorizados. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_storage_container_immutability_policy" "fail_explicit" { - storage_container_resource_manager_id = azurerm_storage_container.example.id - retention_period_in_days = 730 - locked = false # <-- PROBLEMA DETECTADO - } - ``` -* **Ubicación de la Alerta:** Atributo `locked`. - -## Recurso Involucrado - -* `azurerm_storage_container_immutability_policy` - -## Solución - -Establezca el atributo `locked` en `true` para asegurar que el control de integridad de los datos sea permanente y cumpla con los requisitos WORM. - -> [!WARNING] -> **Advertencia Crítica:** Una vez que una política se bloquea en Azure, **no puede eliminarse**. Solo podrá borrar el contenedor una vez que el periodo de retención de todos los objetos haya expirado. Valide cuidadosamente los días de retención antes de aplicar este cambio en producción. - -```terraform -resource "azurerm_storage_container_immutability_policy" "secure_policy" { - storage_container_resource_manager_id = azurerm_storage_container.example.id - retention_period_in_days = 365 - - # SOLUCIÓN: Bloqueo de política habilitado para integridad WORM - locked = true -} \ No newline at end of file +# KICS Rule: Storage Immutability Policy Not Locked + +## General Description + +This rule verifies that immutability policies (`azurerm_storage_container_immutability_policy`) applied to Azure Storage containers are configured in the **Locked** state (`locked = true`). + +Immutability policies allow data to be stored in a **WORM** (Write Once, Read Many) format. In the context of access control and data protection, there are two critical states: +* **Unlocked (Mutable):** The policy protects data against deletion or modification, but the policy itself can be deleted or modified by users with high privileges. It is a transient state and does not guarantee long-term immutability. +* **Locked (Immutable):** Once locked, the policy becomes irreversible; it cannot be deleted and the retention period can only be increased. This state is a strict integrity control that ensures that not even an administrator can delete data ahead of time. + +## Rule Logic + +The rule audits `azurerm_storage_container_immutability_policy` resources by evaluating two control conditions: +1. **Attribute Omission:** If the `locked` attribute is not defined, Azure assumes the "Unlocked" state by default, allowing the protection to be removed. +2. **Incorrect Value:** If the `locked` attribute is explicitly set to `false`. + +## Detected Failure Cases + +### Case 1: Missing Lock Attribute + +* **Description:** A retention policy is defined but it is not specified whether it should be locked. By default, Azure creates it in the "Unlocked" state. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_storage_container_immutability_policy" "fail_missing" { + storage_container_resource_manager_id = azurerm_storage_container.example.id + retention_period_in_days = 365 + # Missing locked = true + } + ``` +* **Alert Location:** On the root `azurerm_storage_container_immutability_policy` resource. + +--- + +### Case 2: Mutable Policy (Unlocked) + +* **Description:** The `locked` attribute is explicitly set to `false`, which allows the immutability policy to be deleted by authorized users. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_storage_container_immutability_policy" "fail_explicit" { + storage_container_resource_manager_id = azurerm_storage_container.example.id + retention_period_in_days = 730 + locked = false # <-- DETECTED ISSUE + } + ``` +* **Alert Location:** `locked` attribute. + +## Involved Resource + +* `azurerm_storage_container_immutability_policy` + +## Solution + +Set the `locked` attribute to `true` to ensure that the data integrity control is permanent and meets WORM requirements. + +> [!WARNING] +> **Critical Warning:** Once a policy is locked in Azure, **it cannot be deleted**. You will only be able to delete the container once the retention period of all objects has expired. Carefully validate the retention days before applying this change in production. + +```terraform +resource "azurerm_storage_container_immutability_policy" "secure_policy" { + storage_container_resource_manager_id = azurerm_storage_container.example.id + retention_period_in_days = 365 + + # SOLUTION: Policy lock enabled for WORM integrity + locked = true +} diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego index 4994a66b173..00b51f85924 100644 --- a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: El atributo 'locked' no está definido (Default es false/unlocked). +# RULE 1: The 'locked' attribute is not defined (Default is false/unlocked). CxPolicy[result] { doc := input.document[i] policy := doc.resource.azurerm_storage_container_immutability_policy[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: El atributo 'locked' está explícitamente a false. +# RULE 2: The 'locked' attribute is explicitly set to false. CxPolicy[result] { doc := input.document[i] policy := doc.resource.azurerm_storage_container_immutability_policy[name] diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/README.md b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/README.md index 1304966919e..9d65a06794d 100644 --- a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/README.md +++ b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/README.md @@ -1,62 +1,62 @@ -# Regla KICS: Critical Data Storage CMK (Manual) - -## Descripción General - -Esta regla identifica cuentas de almacenamiento de Azure (`azurerm_storage_account`) que utilizan cifrado gestionado por Microsoft (**Platform-Managed Keys**). - -El cifrado en reposo es automático en Azure, pero el uso de claves gestionadas por la plataforma no siempre es suficiente para cumplir con normativas de soberanía de datos o requisitos de seguridad de datos críticos. Esta regla actúa como un control de **auditoría manual**: identifica recursos sin **Customer-Managed Keys (CMK)** para que el equipo de seguridad valide si los datos contenidos (financieros, PII, secretos industriales) requieren que la organización posea y gestione las claves de cifrado en su propio Key Vault. - -## Lógica de la Regla - -La política audita el recurso `azurerm_storage_account` evaluando dos escenarios: -1. **Ausencia de Configuración CMK:** Si el bloque `customer_managed_key` no está presente, la cuenta utiliza las claves por defecto de Azure. -2. **Configuración Incompleta:** Si el bloque `customer_managed_key` existe pero no define el atributo `key_vault_key_id`, el cifrado CMK no se está aplicando efectivamente. - -## Casos de Fallo Detectados - -### Caso 1: Revisión de Sensibilidad de Datos Requerida (Cifrado Default) - -* **Descripción:** La cuenta utiliza el cifrado base de Azure. Se requiere validación manual para determinar si la criticidad de los datos exige el paso a CMK. -* **Ubicación de la Alerta:** Recurso `azurerm_storage_account`. - -### Caso 2: Bloque CMK sin Clave Asociada - -* **Descripción:** Se ha declarado el bloque de claves gestionadas por el cliente pero se ha omitido el identificador de la clave criptográfica. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_storage_account" "fail_incomplete" { - name = "stincomplete" - # ... - customer_managed_key { - user_assigned_identity_id = azurerm_user_assigned_identity.example.id - # key_vault_key_id es opcional en el esquema pero necesario para CMK - } - } - ``` -* **Ubicación de la Alerta:** Bloque `customer_managed_key`. - -## Recurso Involucrado - -* `azurerm_storage_account` - -## Solución - -Si tras la revisión manual se confirma que los datos son críticos, implemente CMK vinculando una clave de Azure Key Vault. - -```terraform -resource "azurerm_storage_account" "secure_critical" { - name = "stcriticaldata" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "GRS" - - identity { - type = "SystemAssigned" - } - - customer_managed_key { - # SOLUCIÓN: Definir explícitamente la clave de Key Vault - key_vault_key_id = azurerm_key_vault_key.example.id - } -} \ No newline at end of file +# KICS Rule: Critical Data Storage CMK (Manual) + +## General Description + +This rule identifies Azure storage accounts (`azurerm_storage_account`) that use Microsoft-managed encryption (**Platform-Managed Keys**). + +Encryption at rest is automatic in Azure, but using platform-managed keys is not always sufficient to comply with data sovereignty regulations or critical data security requirements. This rule acts as a **manual audit** control: it identifies resources without **Customer-Managed Keys (CMK)** so that the security team can validate whether the contained data (financial, PII, trade secrets) requires the organization to own and manage the encryption keys in their own Key Vault. + +## Rule Logic + +The policy audits the `azurerm_storage_account` resource by evaluating two scenarios: +1. **Missing CMK Configuration:** If the `customer_managed_key` block is not present, the account uses Azure's default keys. +2. **Incomplete Configuration:** If the `customer_managed_key` block exists but does not define the `key_vault_key_id` attribute, CMK encryption is not being effectively applied. + +## Detected Failure Cases + +### Case 1: Data Sensitivity Review Required (Default Encryption) + +* **Description:** The account uses Azure's base encryption. Manual validation is required to determine whether data criticality warrants a move to CMK. +* **Alert Location:** `azurerm_storage_account` resource. + +### Case 2: CMK Block Without Associated Key + +* **Description:** The customer-managed key block has been declared but the cryptographic key identifier has been omitted. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_storage_account" "fail_incomplete" { + name = "stincomplete" + # ... + customer_managed_key { + user_assigned_identity_id = azurerm_user_assigned_identity.example.id + # key_vault_key_id is optional in the schema but required for CMK + } + } + ``` +* **Alert Location:** `customer_managed_key` block. + +## Involved Resource + +* `azurerm_storage_account` + +## Solution + +If the manual review confirms that the data is critical, implement CMK by linking an Azure Key Vault key. + +```terraform +resource "azurerm_storage_account" "secure_critical" { + name = "stcriticaldata" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "GRS" + + identity { + type = "SystemAssigned" + } + + customer_managed_key { + # SOLUTION: Explicitly define the Key Vault key + key_vault_key_id = azurerm_key_vault_key.example.id + } +} diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego index 49fb3983e7d..c9e0628b9ba 100644 --- a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego +++ b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: El bloque 'customer_managed_key' no existe. +# RULE 1: The 'customer_managed_key' block does not exist. CxPolicy[result] { doc := input.document[i] sa := doc.resource.azurerm_storage_account[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: El bloque existe pero el atributo 'key_vault_key_id' no está definido. +# RULE 2: The block exists but the 'key_vault_key_id' attribute is not defined. CxPolicy[result] { doc := input.document[i] sa := doc.resource.azurerm_storage_account[name] diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/README.md b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/README.md index 3fc500b38a8..2657ba596bb 100644 --- a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/README.md +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/README.md @@ -1,93 +1,93 @@ -# Regla KICS: Storage Queue Service Logging Disabled - -## Descripción General - -Esta regla verifica que el **Logging de Almacenamiento** (Storage Analytics Logging) esté habilitado para el servicio de **Colas (Queue Service)** en las cuentas de almacenamiento de Azure. - -El registro de auditoría es un componente fundamental de la observabilidad. Permite rastrear la actividad detallada en el plano de datos, capturando quién y cuándo interactuó con los mensajes de la cola. La política valida que se registren las siguientes operaciones: -* **Read (Lectura):** Operaciones como la visualización o extracción de mensajes. -* **Write (Escritura):** Operaciones de inserción o actualización de mensajes. -* **Delete (Borrado):** Operaciones de eliminación de mensajes o vaciado de colas. - -Sin esta configuración, las organizaciones pierden la trazabilidad necesaria para investigar comportamientos anómalos o fugas de información a través del servicio de mensajería. - -## Lógica de la Regla - -La política audita tanto la configuración embebida en la cuenta de almacenamiento como el recurso específico de propiedades: -1. **Identificación de Atributos:** Busca la presencia de `queue_properties` en el recurso principal o instancias del recurso independiente. -2. **Validación de Auditoría:** Asegura la existencia del bloque `logging`. -3. **Verificación de Acciones:** Comprueba que `read`, `write` y `delete` estén configurados explícitamente como `true`. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Logging Embebido Ausente - -* **Descripción:** Se definen propiedades de cola en la cuenta de almacenamiento pero no se incluye la configuración de registro. -* **Ubicación de la Alerta:** Bloque `queue_properties` del recurso `azurerm_storage_account`. - ---- - -### Caso 2: Configuración Embebida Incorrecta - -* **Descripción:** El bloque de registro existe en la cuenta de almacenamiento pero alguna de las acciones críticas está desactivada. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "azurerm_storage_account" "fail_logging" { - # ... - queue_properties { - logging { - read = false # <-- PROBLEMA - write = true - delete = true - version = "1.0" - } - } - } - ``` -* **Ubicación de la Alerta:** Atributo `logging` del recurso `azurerm_storage_account`. - ---- - -### Caso 3: Recurso Standalone sin Logging - -* **Descripción:** Se utiliza el recurso `azurerm_storage_account_queue_properties` pero se omite completamente el bloque de registro. -* **Ubicación de la Alerta:** Recurso `azurerm_storage_account_queue_properties`. - ---- - -### Caso 4: Recurso Standalone con Configuración Incorrecta - -* **Descripción:** El recurso independiente de propiedades tiene el bloque de registro, pero con acciones deshabilitadas. -* **Ubicación de la Alerta:** Atributo `logging` del recurso `azurerm_storage_account_queue_properties`. - -## Recursos Involucrados - -* `azurerm_storage_account` -* `azurerm_storage_account_queue_properties` - -## Solución - -Habilite el registro para todas las operaciones (`read`, `write`, `delete`) dentro de la configuración del servicio de colas. - -```terraform -resource "azurerm_storage_account" "secure_queue" { - name = "stsecurequeue" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "LRS" - - queue_properties { - logging { - read = true - write = true - delete = true - version = "1.0" - retention_policy_days = 30 - } - } -} \ No newline at end of file +# KICS Rule: Storage Queue Service Logging Disabled + +## General Description + +This rule verifies that **Storage Logging** (Storage Analytics Logging) is enabled for the **Queue Service** in Azure storage accounts. + +Audit logging is a fundamental component of observability. It allows detailed activity in the data plane to be tracked, capturing who and when interacted with queue messages. The policy validates that the following operations are recorded: +* **Read:** Operations such as viewing or extracting messages. +* **Write:** Message insertion or update operations. +* **Delete:** Message deletion or queue purge operations. + +Without this configuration, organizations lose the traceability needed to investigate anomalous behavior or information leaks through the messaging service. + +## Rule Logic + +The policy audits both the configuration embedded in the storage account and the specific properties resource: +1. **Attribute Identification:** Looks for the presence of `queue_properties` in the main resource or instances of the standalone resource. +2. **Audit Validation:** Ensures the existence of the `logging` block. +3. **Action Verification:** Checks that `read`, `write`, and `delete` are explicitly configured as `true`. + +## Detected Failure Cases + +The following describes the scenarios that this policy will detect. + +--- + +### Case 1: Missing Embedded Logging + +* **Description:** Queue properties are defined in the storage account but the logging configuration is not included. +* **Alert Location:** `queue_properties` block of the `azurerm_storage_account` resource. + +--- + +### Case 2: Incorrect Embedded Configuration + +* **Description:** The logging block exists in the storage account but one of the critical actions is disabled. +* **Problematic Terraform Code Example:** + ```terraform + resource "azurerm_storage_account" "fail_logging" { + # ... + queue_properties { + logging { + read = false # <-- ISSUE + write = true + delete = true + version = "1.0" + } + } + } + ``` +* **Alert Location:** `logging` attribute of the `azurerm_storage_account` resource. + +--- + +### Case 3: Standalone Resource Without Logging + +* **Description:** The `azurerm_storage_account_queue_properties` resource is used but the logging block is completely omitted. +* **Alert Location:** `azurerm_storage_account_queue_properties` resource. + +--- + +### Case 4: Standalone Resource With Incorrect Configuration + +* **Description:** The standalone properties resource has the logging block, but with disabled actions. +* **Alert Location:** `logging` attribute of the `azurerm_storage_account_queue_properties` resource. + +## Involved Resources + +* `azurerm_storage_account` +* `azurerm_storage_account_queue_properties` + +## Solution + +Enable logging for all operations (`read`, `write`, `delete`) within the queue service configuration. + +```terraform +resource "azurerm_storage_account" "secure_queue" { + name = "stsecurequeue" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "LRS" + + queue_properties { + logging { + read = true + write = true + delete = true + version = "1.0" + retention_policy_days = 30 + } + } +} diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego index 4301ed2999d..b77e675c4bc 100644 --- a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego @@ -8,7 +8,7 @@ is_logging_valid(logging) { logging.delete == true } -# CASO 1: Bloque 'logging' ausente en 'queue_properties' de azurerm_storage_account. +# CASE 1: 'logging' block missing in 'queue_properties' of azurerm_storage_account. CxPolicy[result] { doc := input.document[i] sa := doc.resource.azurerm_storage_account[name] @@ -27,7 +27,7 @@ CxPolicy[result] { } } -# CASO 2: Configuración de 'logging' incorrecta en azurerm_storage_account. +# CASE 2: Incorrect 'logging' configuration in azurerm_storage_account. CxPolicy[result] { doc := input.document[i] sa := doc.resource.azurerm_storage_account[name] @@ -46,7 +46,7 @@ CxPolicy[result] { } } -# CASO 3: Bloque 'logging' ausente en el recurso azurerm_storage_account_queue_properties. +# CASE 3: 'logging' block missing in the azurerm_storage_account_queue_properties resource. CxPolicy[result] { doc := input.document[i] props := doc.resource.azurerm_storage_account_queue_properties[name] @@ -64,7 +64,7 @@ CxPolicy[result] { } } -# CASO 4: Configuración de 'logging' incorrecta en azurerm_storage_account_queue_properties. +# CASE 4: Incorrect 'logging' configuration in azurerm_storage_account_queue_properties. CxPolicy[result] { doc := input.document[i] props := doc.resource.azurerm_storage_account_queue_properties[name] diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/README.md b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/README.md index ee83e7ad654..59e0488cdc9 100644 --- a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/README.md +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/README.md @@ -1,52 +1,52 @@ -# Regla KICS: Storage Table Service Logging Disabled - -## Descripción General - -Esta regla verifica que el registro de diagnóstico (**Diagnostic Settings**) esté habilitado y configurado íntegramente para el servicio de **Tablas (Table Service)** en las cuentas de almacenamiento de Azure. - -La auditoría de las tablas NoSQL de Azure Storage permite capturar telemetría sobre quién accede y modifica los datos almacenados. La política asegura que se capturen las tres categorías de operaciones esenciales para una trazabilidad completa: -* **StorageRead:** Auditoría de consultas de entidades y lectura de metadatos de tablas. -* **StorageWrite:** Auditoría de inserciones, actualizaciones y "upserts" de datos. -* **StorageDelete:** Auditoría de eliminaciones de entidades o de la estructura de la tabla. - -Sin estos registros activos, las organizaciones carecen de la telemetría necesaria para identificar accesos no autorizados a datos sensibles o investigar errores en la manipulación de registros NoSQL. - -## Lógica de la Regla - -La política audita el código Terraform evaluando tres niveles de cumplimiento: -1. **Existencia de Recurso:** Verifica que cada `azurerm_storage_account` tenga un recurso `azurerm_monitor_diagnostic_setting` vinculado a su endpoint de tablas (`/tableServices/default`). -2. **Presencia de Logs:** Alerta si el recurso de diagnóstico existe pero el bloque `enabled_log` está ausente. -3. **Integridad de Categorías:** Analiza que las categorías `StorageRead`, `StorageWrite` y `StorageDelete` estén presentes simultáneamente. Si el conjunto está incompleto, la alerta apunta directamente al bloque `enabled_log`. - -## Casos de Fallo Detectados - -### Caso 1: Servicio de Tablas sin Diagnostic Settings -* **Descripción:** La cuenta de almacenamiento no tiene configurado ningún destino de registro para tablas. -* **Ubicación:** `azurerm_storage_account`. - -### Caso 2: Diagnostic Setting sin bloques de Log -* **Descripción:** El recurso de diagnóstico existe pero la configuración de registros está vacía. -* **Ubicación:** `azurerm_monitor_diagnostic_setting`. - -### Caso 3: Auditoría de Tablas Incompleta -* **Descripción:** Faltan una o más categorías críticas en la configuración de logs. -* **Ubicación:** Bloque `enabled_log` dentro de `azurerm_monitor_diagnostic_setting`. - -## Recursos Involucrados -* `azurerm_storage_account` -* `azurerm_monitor_diagnostic_setting` - -## Solución - -Configure un Diagnostic Setting completo para el servicio de tablas. - -```terraform -resource "azurerm_monitor_diagnostic_setting" "secure_table_logging" { - name = "table-audit-complete" - target_resource_id = "${azurerm_storage_account.example.id}/tableServices/default" - storage_account_id = azurerm_storage_account.logs.id - - enabled_log { category = "StorageRead" } - enabled_log { category = "StorageWrite" } - enabled_log { category = "StorageDelete" } -} \ No newline at end of file +# KICS Rule: Storage Table Service Logging Disabled + +## General Description + +This rule verifies that diagnostic logging (**Diagnostic Settings**) is enabled and fully configured for the **Table Service** in Azure storage accounts. + +Auditing Azure Storage NoSQL tables allows capturing telemetry on who accesses and modifies stored data. The policy ensures that the three essential operation categories are captured for complete traceability: +* **StorageRead:** Audit of entity queries and table metadata reads. +* **StorageWrite:** Audit of data insertions, updates, and upserts. +* **StorageDelete:** Audit of entity deletions or table structure deletions. + +Without these active logs, organizations lack the telemetry needed to identify unauthorized access to sensitive data or investigate errors in NoSQL record manipulation. + +## Rule Logic + +The policy audits the Terraform code by evaluating three compliance levels: +1. **Resource Existence:** Verifies that each `azurerm_storage_account` has an `azurerm_monitor_diagnostic_setting` resource linked to its table endpoint (`/tableServices/default`). +2. **Log Presence:** Alerts if the diagnostic resource exists but the `enabled_log` block is absent. +3. **Category Integrity:** Analyzes that the `StorageRead`, `StorageWrite`, and `StorageDelete` categories are all present simultaneously. If the set is incomplete, the alert points directly to the `enabled_log` block. + +## Detected Failure Cases + +### Case 1: Table Service Without Diagnostic Settings +* **Description:** The storage account has no logging destination configured for tables. +* **Location:** `azurerm_storage_account`. + +### Case 2: Diagnostic Setting Without Log Blocks +* **Description:** The diagnostic resource exists but the log configuration is empty. +* **Location:** `azurerm_monitor_diagnostic_setting`. + +### Case 3: Incomplete Table Audit +* **Description:** One or more critical categories are missing from the log configuration. +* **Location:** `enabled_log` block within `azurerm_monitor_diagnostic_setting`. + +## Involved Resources +* `azurerm_storage_account` +* `azurerm_monitor_diagnostic_setting` + +## Solution + +Configure a complete Diagnostic Setting for the table service. + +```terraform +resource "azurerm_monitor_diagnostic_setting" "secure_table_logging" { + name = "table-audit-complete" + target_resource_id = "${azurerm_storage_account.example.id}/tableServices/default" + storage_account_id = azurerm_storage_account.logs.id + + enabled_log { category = "StorageRead" } + enabled_log { category = "StorageWrite" } + enabled_log { category = "StorageDelete" } +} diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego index f42e178f480..33917f2bcd2 100644 --- a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego @@ -14,7 +14,7 @@ is_target_linked(target, sa_name) { contains(target, "tableServices/default") } -# CASO 1: La cuenta de almacenamiento no tiene ningún Diagnostic Setting para Tablas. +# CASE 1: The storage account has no Diagnostic Setting for Tables. CxPolicy[result] { doc := input.document[i] sa := doc.resource.azurerm_storage_account[name] @@ -37,7 +37,7 @@ diag_exists_for_sa(doc, sa_name) { is_target_linked(diag.target_resource_id, sa_name) } -# CASO 2: El Diagnostic Setting existe pero no tiene ningún bloque 'enabled_log'. +# CASE 2: The Diagnostic Setting exists but has no 'enabled_log' blocks. CxPolicy[result] { doc := input.document[i] diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] @@ -56,7 +56,7 @@ CxPolicy[result] { } } -# CASO 3: El Diagnostic Setting tiene bloques 'enabled_log' pero el conjunto está incompleto. +# CASE 3: The Diagnostic Setting has 'enabled_log' blocks but the set is incomplete. CxPolicy[result] { doc := input.document[i] diag := doc.resource.azurerm_monitor_diagnostic_setting[diag_name] diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/README.md b/assets/queries/terraform/gcp/gcp_access_approval_disabled/README.md index dfa9087e47e..2e980f45452 100644 --- a/assets/queries/terraform/gcp/gcp_access_approval_disabled/README.md +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/README.md @@ -1,50 +1,50 @@ -# Regla KICS: GCP Access Approval Disabled - -## Descripción General - -Esta regla de severidad **MEDIA** audita el cumplimiento del control de acceso de terceros en **Google Cloud (GCP)** para los recursos `google_project`. - -**Access Approval** es un control de seguridad avanzado que permite a las organizaciones establecer un paso de aprobación explícito antes de que el personal de Google (Ingeniería o Soporte) pueda acceder a los datos de sus clientes. Mientras que Google cifra los datos por defecto y restringe el acceso mediante políticas internas, Access Approval otorga al cliente la soberanía final: cualquier intento de acceso genera una solicitud por correo electrónico o mediante Cloud Pub/Sub que el cliente debe aprobar manualmente. - -Sin esta configuración, se asume que el personal de Google puede acceder a los recursos para fines de soporte técnico bajo los términos estándar del contrato, lo que puede no ser suficiente para empresas bajo regulaciones estrictas. - -## Lógica de la Regla - -La política realiza dos validaciones en el código Terraform: -1. **Existencia de la Configuración:** Detecta si un `google_project` carece de un recurso `google_access_approval_project_settings` que lo gestione. -2. **Inscripción de Servicios:** Verifica que, de existir la configuración, esta incluya al menos un bloque `enrolled_services`. Un recurso de configuración sin servicios inscritos no protege activamente ningún producto de GCP. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Proyecto sin Access Approval -* **Descripción:** Se provisiona un proyecto en GCP pero no se implementa el flujo de aprobación de acceso de Google. -* **Ubicación de la Alerta:** Bloque del recurso `google_project`. - -### Caso 2: Configuración de Servicios Ausente -* **Descripción:** Se define el recurso de configuración de Access Approval pero se deja vacío el bloque de servicios protegidos. -* **Ubicación de la Alerta:** Recurso `google_access_approval_project_settings`. - -## Recursos Involucrados - -* `google_project` -* `google_access_approval_project_settings` - -## Solución - -Defina el recurso de configuración y asegúrese de inscribir los servicios deseados (o `all` para una cobertura total). - -```terraform -resource "google_access_approval_project_settings" "compliant_settings" { - project_id = google_project.my_secure_project.project_id - - enrolled_services { - cloud_product = "all" # Protege todos los productos compatibles - enrollment_level = "BLOCK_ALL" - } - - notification_emails = ["security-team@tu-empresa.com"] -} \ No newline at end of file +# KICS Rule: GCP Access Approval Disabled + +## Overview + +This **MEDIUM** severity rule audits compliance with third-party access control in **Google Cloud (GCP)** for `google_project` resources. + +**Access Approval** is an advanced security control that allows organizations to establish an explicit approval step before Google personnel (Engineering or Support) can access customer data. While Google encrypts data by default and restricts access through internal policies, Access Approval grants the customer final sovereignty: any access attempt generates a request via email or Cloud Pub/Sub that the customer must manually approve. + +Without this configuration, it is assumed that Google personnel can access resources for technical support purposes under the standard contract terms, which may not be sufficient for companies subject to strict regulations. + +## Rule Logic + +The policy performs two validations in Terraform code: +1. **Configuration Existence:** Detects if a `google_project` lacks a `google_access_approval_project_settings` resource managing it. +2. **Service Enrollment:** Verifies that, if the configuration exists, it includes at least one `enrolled_services` block. A configuration resource without enrolled services does not actively protect any GCP product. + +## Detected Failure Cases + +The following scenarios will be detected by this policy. + +--- + +### Case 1: Project Without Access Approval +* **Description:** A project is provisioned in GCP but the Google access approval workflow is not implemented. +* **Alert Location:** `google_project` resource block. + +### Case 2: Missing Service Configuration +* **Description:** The Access Approval configuration resource is defined but the protected services block is left empty. +* **Alert Location:** `google_access_approval_project_settings` resource. + +## Resources Involved + +* `google_project` +* `google_access_approval_project_settings` + +## Solution + +Define the configuration resource and ensure the desired services are enrolled (or `all` for full coverage). + +```terraform +resource "google_access_approval_project_settings" "compliant_settings" { + project_id = google_project.my_secure_project.project_id + + enrolled_services { + cloud_product = "all" # Protects all compatible products + enrollment_level = "BLOCK_ALL" + } + + notification_emails = ["security-team@your-company.com"] +} diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego b/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego index afc70b2e7cf..efc85cd9f2b 100644 --- a/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# CASO 1: Proyecto sin configuración de Access Approval. +# CASE 1: Project without Access Approval configuration. CxPolicy[result] { doc := input.document[i] project := doc.resource.google_project[name] @@ -25,7 +25,7 @@ CxPolicy[result] { } } -# CASO 2: Access Approval configurado pero sin servicios inscritos. +# CASE 2: Access Approval configured but without enrolled services. CxPolicy[result] { doc := input.document[i] settings := doc.resource.google_access_approval_project_settings[name] diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/README.md b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/README.md index c7b4f8dee59..f3fae1ea44d 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/README.md +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/README.md @@ -1,57 +1,57 @@ -# Regla KICS: Google API Key API Targets Missing - -## Descripción General - -Esta regla de severidad **MEDIA** audita la configuración de las **Google API Keys** (`google_apikeys_key`) para asegurar que el acceso esté limitado exclusivamente a los servicios necesarios. - -Cuando se genera una API Key en Google Cloud, por defecto tiene capacidad para invocar **cualquier API habilitada** en el proyecto. Esto representa un riesgo significativo de seguridad y costos; si una clave se ve comprometida (por ejemplo, al ser expuesta accidentalmente en el código fuente de una aplicación móvil o web), un atacante podría utilizarla para consumir servicios sensibles o de alto coste (como la API de Google Maps o modelos de IA) que no forman parte del propósito original de la aplicación. - -La mejor práctica de seguridad consiste en aplicar restricciones de "API Targets" para que la clave solo funcione con los servicios específicos para los que fue creada. - -## Lógica de la Regla - -La política evalúa dos escenarios de fallo en el código Terraform: -1. **Ausencia de Restricciones:** El recurso no define ningún bloque `restrictions`, dejando la clave totalmente desprotegida. -2. **Falta de Alcance de API:** El recurso define restricciones (como IPs o referrers), pero omite el bloque `api_targets`, permitiendo que esos orígenes autorizados consuman cualquier API del proyecto. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Restricciones Ausentes -* **Descripción:** La clave de API se define sin ningún tipo de control perimetral o de servicio. -* **Ubicación de la Alerta:** Bloque del recurso `google_apikeys_key`. - -### Caso 2: API Targets no Definidos -* **Descripción:** Se aplican restricciones de cliente, pero se mantiene el acceso ilimitado a todos los servicios de Google habilitados en el proyecto. -* **Ubicación de la Alerta:** Atributo `restrictions`. - -## Recurso Involucrado - -* `google_apikeys_key` - -## Solución - -Añada el bloque `api_targets` dentro de la sección `restrictions` especificando los servicios necesarios. - -```terraform -resource "google_apikeys_key" "secure_key" { - name = "production-maps-key" - - restrictions { - # Restricción de origen (ejemplo para navegador) - browser_key_restrictions { - allowed_referrers = ["[https://app.tu-empresa.com/](https://app.tu-empresa.com/)*"] - } - - # Restricción de servicios (Solución) - api_targets { - service = "maps-backend.googleapis.com" - } - api_targets { - service = "places-backend.googleapis.com" - } - } -} \ No newline at end of file +# KICS Rule: Google API Key API Targets Missing + +## Overview + +This **MEDIUM** severity rule audits the configuration of **Google API Keys** (`google_apikeys_key`) to ensure access is limited exclusively to the necessary services. + +When an API Key is generated in Google Cloud, it is capable by default of invoking **any enabled API** in the project. This represents a significant security and cost risk; if a key is compromised (for example, by being accidentally exposed in a mobile or web application's source code), an attacker could use it to consume sensitive or high-cost services (such as the Google Maps API or AI models) that are not part of the application's original purpose. + +The security best practice is to apply "API Targets" restrictions so that the key only works with the specific services for which it was created. + +## Rule Logic + +The policy evaluates two failure scenarios in Terraform code: +1. **Absence of Restrictions:** The resource does not define any `restrictions` block, leaving the key completely unprotected. +2. **Missing API Scope:** The resource defines restrictions (such as IPs or referrers), but omits the `api_targets` block, allowing those authorized origins to consume any API in the project. + +## Detected Failure Cases + +The following scenarios will be detected by this policy. + +--- + +### Case 1: Missing Restrictions +* **Description:** The API key is defined without any perimeter or service controls. +* **Alert Location:** `google_apikeys_key` resource block. + +### Case 2: API Targets Not Defined +* **Description:** Client restrictions are applied, but unlimited access to all Google services enabled in the project is maintained. +* **Alert Location:** `restrictions` attribute. + +## Resource Involved + +* `google_apikeys_key` + +## Solution + +Add the `api_targets` block inside the `restrictions` section specifying the required services. + +```terraform +resource "google_apikeys_key" "secure_key" { + name = "production-maps-key" + + restrictions { + # Origin restriction (example for browser) + browser_key_restrictions { + allowed_referrers = ["[https://app.your-company.com/](https://app.your-company.com/)*"] + } + + # Service restriction (Solution) + api_targets { + service = "maps-backend.googleapis.com" + } + api_targets { + service = "places-backend.googleapis.com" + } + } +} diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego index 14b7ad5a894..128870a4d60 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# CASO 1: No existe el bloque 'restrictions'. +# CASE 1: The 'restrictions' block does not exist. CxPolicy[result] { doc := input.document[i] key := doc.resource.google_apikeys_key[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# CASO 2: Existe 'restrictions', pero falta 'api_targets'. +# CASE 2: 'restrictions' exists, but 'api_targets' is missing. CxPolicy[result] { doc := input.document[i] key := doc.resource.google_apikeys_key[name] diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/README.md b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/README.md index 348522b5c62..3f8037b9bbc 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/README.md +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/README.md @@ -1,54 +1,54 @@ -# Regla KICS: Google API Key Restrictions (Manual) - -## Descripción General - -Esta regla informativa (INFO) audita la seguridad perimetral de las **Google API Keys** (`google_apikeys_key`). - -A diferencia de las identidades de IAM, las API Keys no se autentican mediante un usuario, sino que se validan por su simple posesión. Por ello, es imperativo restringir su uso a direcciones IP, dominios web o aplicaciones móviles específicas. - -Esta regla garantiza que se aplique el principio de defensa en profundidad. Dado que una herramienta de análisis estático no puede determinar si una dirección IP o un dominio configurado es legítimo o excesivamente permisivo, la regla alerta tanto ante la ausencia de restricciones como ante su presencia, forzando una revisión manual de la lista de permitidos. - -## Lógica de la Regla - -La política evalúa el recurso en dos etapas: -1. **Validación de Presencia:** Si falta el bloque `restrictions`, la clave se marca como vulnerable (acceso público). -2. **Validación Manual:** Si el bloque `restrictions` existe, se genera una alerta informativa para que el auditor confirme que los valores (IPs, referrers, etc.) coinciden con los activos corporativos autorizados. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Sin Restricciones (Vulnerable) -* **Descripción:** La clave de API carece de restricciones de cliente, permitiendo que cualquier persona con la clave pueda realizar llamadas desde cualquier lugar de Internet. -* **Ubicación de la Alerta:** Bloque del recurso `google_apikeys_key`. - -### Caso 2: Revisión de Restricciones (Manual Check) -* **Descripción:** La clave tiene restricciones configuradas. El auditor debe verificar que los valores definidos no sean genéricos o incorrectos. -* **Ubicación de la Alerta:** Atributo `restrictions`. - -## Recurso Involucrado - -* `google_apikeys_key` - -## Solución - -Implemente siempre el bloque `restrictions` utilizando el tipo de restricción que mejor se adapte al uso de la clave (Browser, Server, Android o iOS). - -```terraform -resource "google_apikeys_key" "secure_api_key" { - name = "frontend-maps-key" - - restrictions { - # Ejemplo: Clave restringida a un dominio específico - browser_key_restrictions { - allowed_referrers = ["[https://app.example.com/](https://app.example.com/)*"] - } - - # Recomendado: Combinar con restricción de API (API Targets) - api_targets { - service = "maps-backend.googleapis.com" - } - } -} \ No newline at end of file +# KICS Rule: Google API Key Restrictions (Manual) + +## Overview + +This informational (INFO) rule audits the perimeter security of **Google API Keys** (`google_apikeys_key`). + +Unlike IAM identities, API Keys are not authenticated by a user; they are validated by simple possession. Therefore, it is imperative to restrict their use to specific IP addresses, web domains, or mobile applications. + +This rule ensures that the defense-in-depth principle is applied. Since a static analysis tool cannot determine whether a configured IP address or domain is legitimate or overly permissive, the rule alerts both on the absence of restrictions and on their presence, forcing a manual review of the allowlist. + +## Rule Logic + +The policy evaluates the resource in two stages: +1. **Presence Validation:** If the `restrictions` block is missing, the key is flagged as vulnerable (public access). +2. **Manual Validation:** If the `restrictions` block exists, an informational alert is generated so the auditor can confirm that the values (IPs, referrers, etc.) match the authorized corporate assets. + +## Detected Failure Cases + +The following scenarios will be detected by this policy. + +--- + +### Case 1: No Restrictions (Vulnerable) +* **Description:** The API key lacks client restrictions, allowing anyone with the key to make calls from anywhere on the Internet. +* **Alert Location:** `google_apikeys_key` resource block. + +### Case 2: Restrictions Review (Manual Check) +* **Description:** The key has restrictions configured. The auditor must verify that the defined values are not generic or incorrect. +* **Alert Location:** `restrictions` attribute. + +## Resource Involved + +* `google_apikeys_key` + +## Solution + +Always implement the `restrictions` block using the restriction type that best suits the key's use case (Browser, Server, Android, or iOS). + +```terraform +resource "google_apikeys_key" "secure_api_key" { + name = "frontend-maps-key" + + restrictions { + # Example: Key restricted to a specific domain + browser_key_restrictions { + allowed_referrers = ["[https://app.example.com/](https://app.example.com/)*"] + } + + # Recommended: Combine with API restriction (API Targets) + api_targets { + service = "maps-backend.googleapis.com" + } + } +} diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/README.md b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/README.md index 827f151e803..bd9bb67832d 100644 --- a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/README.md +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/README.md @@ -1,57 +1,57 @@ -# Regla KICS: App Engine HTTPS Enforcement (Manual) - -## Descripción General - -Esta regla de auditoría verifica que las aplicaciones desplegadas en **Google App Engine** (Standard Environment) fuercen el uso exclusivo de conexiones cifradas mediante **HTTPS**. - -Servir contenido a través de HTTP sin cifrar expone los datos confidenciales de los usuarios y las credenciales de sesión a intercepciones. Para mitigar este riesgo, App Engine permite configurar una redirección automática de HTTP a HTTPS. - -Dado que App Engine suele utilizar un archivo de configuración externo (`app.yaml`) para definir el comportamiento de red, esta regla actúa como un control de gobierno que alerta si la política no está explícitamente definida en la infraestructura como código (Terraform) o si requiere una inspección manual de los artefactos de despliegue. - -## Lógica de la Regla - -La política evalúa el recurso `google_app_engine_standard_app_version` bajo dos escenarios: -1. **Configuración en Terraform:** Si el bloque `handlers` está presente, se asegura de que el atributo `security_level` esté configurado como `SECURE_ALWAYS`. Cualquier otro valor (como `SECURE_OPTIONAL`) disparará una alerta. -2. **Configuración Externa:** Si no se definen `handlers` en Terraform, la regla genera una alerta informativa (**INFO**) indicando que el cumplimiento depende de la configuración dentro del archivo `app.yaml` de la aplicación. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Nivel de Seguridad Inadecuado en Terraform -* **Descripción:** Los manejadores de URL permiten tráfico HTTP o no fuerzan la redirección segura. -* **Ubicación de la Alerta:** Atributo `handlers` dentro del recurso App Engine. - -### Caso 2: Verificación Manual de Archivos de Configuración -* **Descripción:** Terraform no gestiona la lógica de rutas. Se requiere validar el código fuente. -* **Acción Requerida:** Confirmar que en `app.yaml` todos los handlers críticos contengan: - ```yaml - secure: always - ``` -* **Ubicación de la Alerta:** Nivel de recurso `google_app_engine_standard_app_version`. - -## Recurso Involucrado - -* `google_app_engine_standard_app_version` - -## Solución - -Para forzar HTTPS desde Terraform, configure el `security_level` en cada handler: - -```terraform -resource "google_app_engine_standard_app_version" "secure_app" { - service = "api-service" - version_id = "v2" - runtime = "nodejs18" - - handlers { - url_regex = "/.*" - script { - script_path = "auto" - } - # Solución técnica - security_level = "SECURE_ALWAYS" - } -} \ No newline at end of file +# KICS Rule: App Engine HTTPS Enforcement (Manual) + +## Overview + +This audit rule verifies that applications deployed on **Google App Engine** (Standard Environment) enforce the exclusive use of encrypted connections via **HTTPS**. + +Serving content over unencrypted HTTP exposes users' confidential data and session credentials to interception. To mitigate this risk, App Engine allows configuring an automatic HTTP to HTTPS redirect. + +Since App Engine typically uses an external configuration file (`app.yaml`) to define network behavior, this rule acts as a governance control that alerts if the policy is not explicitly defined in the infrastructure as code (Terraform) or if it requires manual inspection of deployment artifacts. + +## Rule Logic + +The policy evaluates the `google_app_engine_standard_app_version` resource under two scenarios: +1. **Terraform Configuration:** If the `handlers` block is present, it ensures that the `security_level` attribute is configured as `SECURE_ALWAYS`. Any other value (such as `SECURE_OPTIONAL`) will trigger an alert. +2. **External Configuration:** If no `handlers` are defined in Terraform, the rule generates an informational alert (**INFO**) indicating that compliance depends on the configuration within the application's `app.yaml` file. + +## Detected Failure Cases + +The following scenarios will be detected by this policy. + +--- + +### Case 1: Insecure Security Level in Terraform +* **Description:** URL handlers allow HTTP traffic or do not enforce secure redirection. +* **Alert Location:** `handlers` attribute within the App Engine resource. + +### Case 2: Manual Verification of Configuration Files +* **Description:** Terraform does not manage routing logic. The source code must be validated. +* **Required Action:** Confirm that in `app.yaml` all critical handlers contain: + ```yaml + secure: always + ``` +* **Alert Location:** `google_app_engine_standard_app_version` resource level. + +## Resource Involved + +* `google_app_engine_standard_app_version` + +## Solution + +To enforce HTTPS from Terraform, configure `security_level` in each handler: + +```terraform +resource "google_app_engine_standard_app_version" "secure_app" { + service = "api-service" + version_id = "v2" + runtime = "nodejs18" + + handlers { + url_regex = "/.*" + script { + script_path = "auto" + } + # Technical solution + security_level = "SECURE_ALWAYS" + } +} diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego index 99bb9112a85..17683e522ca 100644 --- a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego @@ -5,7 +5,7 @@ import data.generic.terraform as tf_lib ensure_array(x) = x { is_array(x) } ensure_array(x) = [x] { not is_array(x) } -# CASO 1: Configuración Insegura en los handlers definidos. +# CASE 1: Insecure configuration in the defined handlers. CxPolicy[result] { doc := input.document[i] app := doc.resource.google_app_engine_standard_app_version[name] @@ -29,7 +29,7 @@ CxPolicy[result] { } } -# CASO 2: Configuración Ausente en Terraform (Requiere revisión de app.yaml). +# CASE 2: Configuration Missing in Terraform (Requires review of app.yaml). CxPolicy[result] { doc := input.document[i] app := doc.resource.google_app_engine_standard_app_version[name] diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/README.md b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/README.md index 133689f6385..d0c6b8394cf 100644 --- a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/README.md +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/README.md @@ -1,49 +1,49 @@ -# Regla KICS: GCP Compute Logging Service Disabled - -## Descripción General - -Esta regla de **Observabilidad** verifica que las instancias de **Google Compute Engine** (`google_compute_instance`) tengan habilitado el envío de registros al servicio de **Cloud Logging** mediante el metadato `google-logging-enabled`. - -La visibilidad es un componente crítico de la seguridad. El agente de Google Cloud (Ops Agent) utiliza este flag para determinar si debe transmitir logs del sistema operativo y de aplicaciones a la consola centralizada de Google Cloud. Sin estos registros, la detección de intrusiones, el análisis forense y la resolución de errores operativos se vuelven tareas inviables. - -## Lógica de la Regla - -La política audita el recurso evaluando tres estados posibles de fallo para maximizar la precisión del reporte: -1. **Bloque Ausente:** Si falta todo el bloque `metadata`. -2. **Clave Ausente:** Si el bloque `metadata` existe pero no define la clave requerida. -3. **Valor Incorrecto:** Si la clave existe pero se ha establecido explícitamente como `"false"`. - -## Casos de Fallo Detectados - ---- - -### Caso 1: Configuración de Metadatos Ausente -* **Descripción:** La instancia no define ningún metadato, omitiendo por tanto el servicio de logging. -* **Ubicación de la Alerta:** Nivel de recurso `google_compute_instance`. - -### Caso 2: Flag de Logging Faltante -* **Descripción:** Se usan metadatos pero se omite específicamente `google-logging-enabled`. -* **Ubicación de la Alerta:** Atributo `metadata`. - -### Caso 3: Logging Deshabilitado -* **Descripción:** Se ha configurado el valor `"false"`, bloqueando activamente la ingesta de logs. -* **Ubicación de la Alerta:** Atributo `google-logging-enabled`. - -## Recurso Involucrado - -* `google_compute_instance` - -## Solución - -Asegúrese de establecer el metadato en `"true"` para habilitar el servicio. - -```terraform -resource "google_compute_instance" "secure_vm" { - name = "prod-server" - machine_type = "e2-medium" - zone = "us-central1-a" - - metadata = { - "google-logging-enabled" = "true" - } -} \ No newline at end of file +# KICS Rule: GCP Compute Logging Service Disabled + +## Overview + +This **Observability** rule verifies that **Google Compute Engine** instances (`google_compute_instance`) have logging to the **Cloud Logging** service enabled via the `google-logging-enabled` metadata key. + +Visibility is a critical security component. The Google Cloud agent (Ops Agent) uses this flag to determine whether to transmit operating system and application logs to the centralized Google Cloud console. Without these logs, intrusion detection, forensic analysis, and resolution of operational errors become impractical tasks. + +## Rule Logic + +The policy audits the resource by evaluating three possible failure states to maximize reporting accuracy: +1. **Missing Block:** If the entire `metadata` block is absent. +2. **Missing Key:** If the `metadata` block exists but does not define the required key. +3. **Incorrect Value:** If the key exists but has been explicitly set to `"false"`. + +## Detected Failure Cases + +--- + +### Case 1: Missing Metadata Configuration +* **Description:** The instance does not define any metadata, therefore omitting the logging service. +* **Alert Location:** `google_compute_instance` resource level. + +### Case 2: Missing Logging Flag +* **Description:** Metadata is used but `google-logging-enabled` is specifically omitted. +* **Alert Location:** `metadata` attribute. + +### Case 3: Logging Disabled +* **Description:** The value `"false"` has been configured, actively blocking log ingestion. +* **Alert Location:** `google-logging-enabled` attribute. + +## Resource Involved + +* `google_compute_instance` + +## Solution + +Ensure the metadata is set to `"true"` to enable the service. + +```terraform +resource "google_compute_instance" "secure_vm" { + name = "prod-server" + machine_type = "e2-medium" + zone = "us-central1-a" + + metadata = { + "google-logging-enabled" = "true" + } +} diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego index 9ffa856729b..d6635bb0742 100644 --- a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: El bloque 'metadata' no existe. +# RULE 1: The 'metadata' block does not exist. CxPolicy[result] { doc := input.document[i] instance := doc.resource.google_compute_instance[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: El bloque 'metadata' existe pero le falta la clave 'google-logging-enabled'. +# RULE 2: The 'metadata' block exists but is missing the 'google-logging-enabled' key. CxPolicy[result] { doc := input.document[i] instance := doc.resource.google_compute_instance[name] @@ -39,7 +39,7 @@ CxPolicy[result] { } } -# REGLA 3: La clave existe pero su valor es 'false'. +# RULE 3: The key exists but its value is 'false'. CxPolicy[result] { doc := input.document[i] instance := doc.resource.google_compute_instance[name] diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/README.md b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/README.md index 7e218cf2b69..467b528e1b2 100644 --- a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/README.md +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/README.md @@ -1,51 +1,51 @@ -# Regla KICS: GKE Default Service Account Used - -## Descripción General - -Esta regla de severidad **ALTA** verifica que los clústeres y pools de nodos de **Google Kubernetes Engine (GKE)** no utilicen la cuenta de servicio predeterminada de Compute Engine. - -Por defecto, si no se especifica el atributo `service_account`, GKE utiliza la cuenta de servicio predeterminada del proyecto (`PROJECT_NUMBER-compute@developer.gserviceaccount.com`). Esta cuenta posee automáticamente el rol de **Editor**, lo que otorga a los nodos (y potencialmente a los Pods) permisos extensos para modificar recursos en GCP, como buckets de almacenamiento, redes VPC y otras instancias. Utilizar una cuenta de servicio dedicada con privilegios mínimos reduce drásticamente el "blast radius" en caso de un compromiso de seguridad en el clúster. - -## Lógica de la Regla - -La política audita los recursos `google_container_cluster` y `google_container_node_pool` bajo los siguientes criterios: -1. **Falta de Atributo:** Identifica si el bloque `node_config` carece de la clave `service_account`. -2. **Identificación de Riesgo:** La alerta se dispara al detectar que el clúster delegará su identidad a la cuenta de servicio más privilegiada del proyecto por defecto. - -## Casos de Fallo Detectados - ---- - -### Caso 1: Uso Implícito en el Clúster -* **Descripción:** Se define un clúster de GKE sin especificar una identidad para los nodos. -* **Ubicación de la Alerta:** Atributo `node_config` del recurso `google_container_cluster`. - -### Caso 2: Uso Implícito en el Node Pool -* **Descripción:** Se crea un pool de nodos adicional que hereda la cuenta de servicio por defecto. -* **Ubicación de la Alerta:** Atributo `node_config` del recurso `google_container_node_pool`. - -## Recurso Involucrado - -* `google_container_cluster` -* `google_container_node_pool` - -## Solución - -Cree una Service Account personalizada con los permisos mínimos necesarios (ej. roles de logging, monitoring y acceso a registry) y asígnela explícitamente. - -```terraform -resource "google_service_account" "gke_nodes_sa" { - account_id = "gke-nodes-identity" - display_name = "GKE Nodes Minimal Service Account" -} - -resource "google_container_cluster" "secure_cluster" { - name = "production-cluster" - location = "us-central1" - - node_config { - # Solución: Identidad dedicada - service_account = google_service_account.gke_nodes_sa.email - oauth_scopes = ["[https://www.googleapis.com/auth/cloud-platform](https://www.googleapis.com/auth/cloud-platform)"] - } -} \ No newline at end of file +# KICS Rule: GKE Default Service Account Used + +## Overview + +This **HIGH** severity rule verifies that **Google Kubernetes Engine (GKE)** clusters and node pools do not use the default Compute Engine service account. + +By default, if the `service_account` attribute is not specified, GKE uses the project's default service account (`PROJECT_NUMBER-compute@developer.gserviceaccount.com`). This account automatically has the **Editor** role, which grants nodes (and potentially Pods) extensive permissions to modify resources in GCP, such as storage buckets, VPC networks, and other instances. Using a dedicated service account with minimal privileges drastically reduces the "blast radius" in the event of a security compromise in the cluster. + +## Rule Logic + +The policy audits the `google_container_cluster` and `google_container_node_pool` resources under the following criteria: +1. **Missing Attribute:** Identifies if the `node_config` block lacks the `service_account` key. +2. **Risk Identification:** The alert is triggered upon detecting that the cluster will delegate its identity to the project's most privileged service account by default. + +## Detected Failure Cases + +--- + +### Case 1: Implicit Use in Cluster +* **Description:** A GKE cluster is defined without specifying an identity for the nodes. +* **Alert Location:** `node_config` attribute of the `google_container_cluster` resource. + +### Case 2: Implicit Use in Node Pool +* **Description:** An additional node pool is created that inherits the default service account. +* **Alert Location:** `node_config` attribute of the `google_container_node_pool` resource. + +## Resources Involved + +* `google_container_cluster` +* `google_container_node_pool` + +## Solution + +Create a custom Service Account with the minimum necessary permissions (e.g., logging, monitoring, and registry access roles) and assign it explicitly. + +```terraform +resource "google_service_account" "gke_nodes_sa" { + account_id = "gke-nodes-identity" + display_name = "GKE Nodes Minimal Service Account" +} + +resource "google_container_cluster" "secure_cluster" { + name = "production-cluster" + location = "us-central1" + + node_config { + # Solution: Dedicated identity + service_account = google_service_account.gke_nodes_sa.email + oauth_scopes = ["[https://www.googleapis.com/auth/cloud-platform](https://www.googleapis.com/auth/cloud-platform)"] + } +} diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego index b9ceb1e587f..e2f1e6b1003 100644 --- a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: Service Account ausente en google_container_cluster. +# RULE 1: Service Account missing in google_container_cluster. CxPolicy[result] { doc := input.document[i] resource := doc.resource.google_container_cluster[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: Service Account ausente en google_container_node_pool. +# RULE 2: Service Account missing in google_container_node_pool. CxPolicy[result] { doc := input.document[i] resource := doc.resource.google_container_node_pool[name] diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/README.md b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/README.md index 8cc831522a7..647e3bc06ea 100644 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/README.md +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/README.md @@ -1,46 +1,46 @@ -# Regla KICS: GKE Image Vulnerability Scanning Disabled - -## Descripción General - -Esta regla de severidad **ALTA** verifica que el escaneo automático de vulnerabilidades esté habilitado en los clústeres de **Google Kubernetes Engine (GKE)** a través del Security Posture Dashboard. - -Habilitar el escaneo de vulnerabilidades permite a GKE inspeccionar continuamente las imágenes de contenedor que se ejecutan en las cargas de trabajo del clúster. GKE compara los paquetes del sistema operativo del contenedor con bases de datos públicas de vulnerabilidades (CVEs). Sin esta función activa, la organización carece de visibilidad sobre si las aplicaciones desplegadas contienen fallos de seguridad conocidos que podrían ser explotados por atacantes. - -## Lógica de la Regla - -La política audita el recurso `google_container_cluster` evaluando tres estados de riesgo: -1. **Omisión de Configuración:** El clúster no tiene definido el bloque `security_posture_config`. -2. **Modo No Especificado:** El bloque existe pero no define el parámetro `vulnerability_mode`. -3. **Deshabilitación Explícita:** El parámetro `vulnerability_mode` está configurado como `VULNERABILITY_DISABLED`. - -## Casos de Fallo Detectados - ---- - -### Caso 1: Configuración de Postura de Seguridad Ausente -* **Descripción:** El clúster se aprovisiona con la configuración por defecto de Google, que no siempre incluye el escaneo avanzado activo. -* **Ubicación de la Alerta:** Nivel de recurso `google_container_cluster`. - -### Caso 2: Vulnerability Mode Faltante o Deshabilitado -* **Descripción:** Se define la configuración de seguridad pero se omite o se desactiva explícitamente el escaneo de imágenes. -* **Ubicación de la Alerta:** Atributo `vulnerability_mode` dentro de `security_posture_config`. - -## Recurso Involucrado - -* `google_container_cluster` - -## Solución - -Habilite el escaneo configurando el bloque `security_posture_config` con un modo de vulnerabilidad válido. - -```terraform -resource "google_container_cluster" "compliant_cluster" { - name = "secure-production-cluster" - location = "us-central1" - - # Solución recomendada - security_posture_config { - mode = "BASIC" - vulnerability_mode = "VULNERABILITY_BASIC" - } -} \ No newline at end of file +# KICS Rule: GKE Image Vulnerability Scanning Disabled + +## Overview + +This **HIGH** severity rule verifies that automatic vulnerability scanning is enabled in **Google Kubernetes Engine (GKE)** clusters through the Security Posture Dashboard. + +Enabling vulnerability scanning allows GKE to continuously inspect the container images running in the cluster's workloads. GKE compares container OS packages against public vulnerability databases (CVEs). Without this feature active, the organization lacks visibility into whether deployed applications contain known security flaws that could be exploited by attackers. + +## Rule Logic + +The policy audits the `google_container_cluster` resource by evaluating three risk states: +1. **Configuration Omission:** The cluster does not have the `security_posture_config` block defined. +2. **Unspecified Mode:** The block exists but does not define the `vulnerability_mode` parameter. +3. **Explicit Disabling:** The `vulnerability_mode` parameter is configured as `VULNERABILITY_DISABLED`. + +## Detected Failure Cases + +--- + +### Case 1: Missing Security Posture Configuration +* **Description:** The cluster is provisioned with Google's default configuration, which does not always include active advanced scanning. +* **Alert Location:** `google_container_cluster` resource level. + +### Case 2: Vulnerability Mode Missing or Disabled +* **Description:** The security configuration is defined but image scanning is omitted or explicitly disabled. +* **Alert Location:** `vulnerability_mode` attribute within `security_posture_config`. + +## Resource Involved + +* `google_container_cluster` + +## Solution + +Enable scanning by configuring the `security_posture_config` block with a valid vulnerability mode. + +```terraform +resource "google_container_cluster" "compliant_cluster" { + name = "secure-production-cluster" + location = "us-central1" + + # Recommended solution + security_posture_config { + mode = "BASIC" + vulnerability_mode = "VULNERABILITY_BASIC" + } +} diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego index c5017869da3..b843d13d5fb 100644 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: Bloque 'security_posture_config' ausente. +# RULE 1: 'security_posture_config' block missing. CxPolicy[result] { doc := input.document[i] cluster := doc.resource.google_container_cluster[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: Atributo 'vulnerability_mode' ausente dentro del bloque. +# RULE 2: 'vulnerability_mode' attribute missing within the block. CxPolicy[result] { doc := input.document[i] cluster := doc.resource.google_container_cluster[name] @@ -39,7 +39,7 @@ CxPolicy[result] { } } -# REGLA 3: Atributo 'vulnerability_mode' configurado como 'VULNERABILITY_DISABLED'. +# RULE 3: 'vulnerability_mode' attribute configured as 'VULNERABILITY_DISABLED'. CxPolicy[result] { doc := input.document[i] cluster := doc.resource.google_container_cluster[name] diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/README.md b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/README.md index 79981201ecc..6b96716f89c 100644 --- a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/README.md +++ b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/README.md @@ -1,38 +1,38 @@ -# Regla KICS: GKE Service Account IAM Review (Manual) - -## Descripción General - -Esta regla informativa (INFO) de **Supply Chain** audita las identidades utilizadas por los nodos de **Google Kubernetes Engine (GKE)** cuando se han configurado cuentas de servicio personalizadas. - -El uso de cuentas de servicio personalizadas es el primer paso hacia el principio de menor privilegio. Sin embargo, si a esta cuenta se le asignan roles con permisos de escritura (como `roles/artifactregistry.writer` o `roles/storage.objectAdmin`), un atacante que comprometa un nodo podría modificar o reemplazar las imágenes de contenedor en el registro. Esto permitiría ataques de persistencia o escalada de privilegios en otros clústeres que consuman esas mismas imágenes. - -## Lógica de la Regla - -La política identifica los recursos `google_container_cluster` y `google_container_node_pool` que definen explícitamente una `service_account`. Al ser una verificación manual, genera una alerta informativa sobre la línea de la cuenta de servicio para que el auditor valide en el proyecto de GCP que los roles asociados son exclusivamente de **Lectura**. - -## Casos de Fallo Detectados - ---- - -### Caso 1: Revisión de SA en Clúster -* **Descripción:** Se ha definido una identidad personalizada para el clúster. Se debe verificar que no tenga permisos de "Push" al registro de imágenes. -* **Ubicación de la Alerta:** Atributo `service_account` en `google_container_cluster`. - -### Caso 2: Revisión de SA en Node Pool -* **Descripción:** Un pool de nodos específico utiliza una identidad propia que requiere auditoría de roles IAM. -* **Ubicación de la Alerta:** Atributo `service_account` en `google_container_node_pool`. - -## Recurso Involucrado - -* `google_container_cluster` -* `google_container_node_pool` - -## Solución - -Asegúrese de que la Service Account asignada solo posea roles de lectura para el registro de imágenes utilizado. - -**Roles Recomendados:** -* `roles/artifactregistry.reader` (para Artifact Registry) -* `roles/storage.objectViewer` (para Container Registry/GCR) -* `roles/logging.logWriter` -* `roles/monitoring.metricWriter` \ No newline at end of file +# KICS Rule: GKE Service Account IAM Review (Manual) + +## Overview + +This informational (INFO) **Supply Chain** rule audits the identities used by **Google Kubernetes Engine (GKE)** nodes when custom service accounts have been configured. + +Using custom service accounts is the first step toward the principle of least privilege. However, if this account is assigned roles with write permissions (such as `roles/artifactregistry.writer` or `roles/storage.objectAdmin`), an attacker who compromises a node could modify or replace container images in the registry. This would enable persistence or privilege escalation attacks in other clusters that consume those same images. + +## Rule Logic + +The policy identifies `google_container_cluster` and `google_container_node_pool` resources that explicitly define a `service_account`. As a manual check, it generates an informational alert on the service account line so the auditor can validate in the GCP project that the associated roles are exclusively **Read-Only**. + +## Detected Failure Cases + +--- + +### Case 1: SA Review in Cluster +* **Description:** A custom identity has been defined for the cluster. It must be verified that it does not have "Push" permissions to the image registry. +* **Alert Location:** `service_account` attribute in `google_container_cluster`. + +### Case 2: SA Review in Node Pool +* **Description:** A specific node pool uses its own identity that requires IAM role auditing. +* **Alert Location:** `service_account` attribute in `google_container_node_pool`. + +## Resources Involved + +* `google_container_cluster` +* `google_container_node_pool` + +## Solution + +Ensure that the assigned Service Account only has read roles for the image registry used. + +**Recommended Roles:** +* `roles/artifactregistry.reader` (for Artifact Registry) +* `roles/storage.objectViewer` (for Container Registry/GCR) +* `roles/logging.logWriter` +* `roles/monitoring.metricWriter` diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego index 7b9f30995d0..d7a7348ad02 100644 --- a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: Detección de SA personalizada en google_container_cluster. +# RULE 1: Detection of custom SA in google_container_cluster. CxPolicy[result] { doc := input.document[i] resource := doc.resource.google_container_cluster[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: Detección de SA personalizada en google_container_node_pool. +# RULE 2: Detection of custom SA in google_container_node_pool. CxPolicy[result] { doc := input.document[i] resource := doc.resource.google_container_node_pool[name] diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/README.md b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/README.md index cf6928760c7..d74f643dd65 100644 --- a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/README.md +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/README.md @@ -1,47 +1,47 @@ -# Regla KICS: GKE Metadata Server Disabled - -## Descripción General - -Esta regla de severidad **ALTA** verifica que los nodos de GKE utilicen el **GKE Metadata Server** para gestionar las identidades de las cargas de trabajo. - -Por defecto, los nodos de GKE tienen acceso al servidor de metadatos de Compute Engine (GCE), el cual expone información sensible del host y tokens de acceso de la cuenta de servicio del nodo. Si un atacante logra comprometer un pod, podría consultar este endpoint para obtener credenciales y realizar un movimiento lateral hacia otros recursos del proyecto. Al habilitar `GKE_METADATA`, se activa el puente hacia **Workload Identity**, interceptando estas peticiones y limitando el acceso solo a lo que el Pod tiene permitido específicamente. - -## Lógica de la Regla - -La política audita los recursos `google_container_cluster` y `google_container_node_pool` bajo dos criterios: -1. **Omisión del Bloque:** Verifica si `workload_metadata_config` está presente dentro de `node_config`. -2. **Modo Inseguro:** Asegura que el atributo `mode` sea estrictamente `GKE_METADATA`. El valor `GCE_METADATA` (valor predeterminado heredado) se considera vulnerable. - -## Casos de Fallo Detectados - ---- - -### Caso 1: Configuración de Metadatos Ausente -* **Descripción:** El clúster o pool de nodos no define el modo de metadatos de carga de trabajo. -* **Ubicación de la Alerta:** Atributo `node_config`. - -### Caso 2: Uso de GCE_METADATA (Legacy/Vulnerable) -* **Descripción:** Se permite explícitamente el acceso de los pods a los metadatos de la instancia de cómputo subyacente. -* **Ubicación de la Alerta:** Atributo `mode` dentro de `workload_metadata_config`. - -## Recurso Involucrado - -* `google_container_cluster` -* `google_container_node_pool` - -## Solución - -Configure el bloque `workload_metadata_config` con el modo `GKE_METADATA`. - -```terraform -resource "google_container_node_pool" "compliant_pool" { - name = "secure-pool" - cluster = google_container_cluster.primary.name - - node_config { - # Solución técnica - workload_metadata_config { - mode = "GKE_METADATA" - } - } -} \ No newline at end of file +# KICS Rule: GKE Metadata Server Disabled + +## Overview + +This **HIGH** severity rule verifies that GKE nodes use the **GKE Metadata Server** to manage workload identities. + +By default, GKE nodes have access to the Compute Engine (GCE) metadata server, which exposes sensitive host information and node service account access tokens. If an attacker manages to compromise a pod, they could query this endpoint to obtain credentials and perform lateral movement to other project resources. By enabling `GKE_METADATA`, the bridge to **Workload Identity** is activated, intercepting these requests and limiting access to only what the Pod is specifically permitted. + +## Rule Logic + +The policy audits the `google_container_cluster` and `google_container_node_pool` resources under two criteria: +1. **Block Omission:** Verifies if `workload_metadata_config` is present within `node_config`. +2. **Insecure Mode:** Ensures that the `mode` attribute is strictly `GKE_METADATA`. The value `GCE_METADATA` (legacy default value) is considered vulnerable. + +## Detected Failure Cases + +--- + +### Case 1: Missing Metadata Configuration +* **Description:** The cluster or node pool does not define the workload metadata mode. +* **Alert Location:** `node_config` attribute. + +### Case 2: Use of GCE_METADATA (Legacy/Vulnerable) +* **Description:** Pods are explicitly allowed access to the underlying compute instance metadata. +* **Alert Location:** `mode` attribute within `workload_metadata_config`. + +## Resources Involved + +* `google_container_cluster` +* `google_container_node_pool` + +## Solution + +Configure the `workload_metadata_config` block with the `GKE_METADATA` mode. + +```terraform +resource "google_container_node_pool" "compliant_pool" { + name = "secure-pool" + cluster = google_container_cluster.primary.name + + node_config { + # Technical solution + workload_metadata_config { + mode = "GKE_METADATA" + } + } +} diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego index 039d2b33472..ef477f34506 100644 --- a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: 'workload_metadata_config' ausente en google_container_cluster +# RULE 1: 'workload_metadata_config' missing in google_container_cluster CxPolicy[result] { doc := input.document[i] resource := doc.resource.google_container_cluster[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: 'workload_metadata_config' ausente en google_container_node_pool +# RULE 2: 'workload_metadata_config' missing in google_container_node_pool CxPolicy[result] { doc := input.document[i] resource := doc.resource.google_container_node_pool[name] @@ -38,7 +38,7 @@ CxPolicy[result] { } } -# REGLA 3: Modo incorrecto en google_container_cluster +# RULE 3: Incorrect mode in google_container_cluster CxPolicy[result] { doc := input.document[i] resource := doc.resource.google_container_cluster[name] @@ -56,7 +56,7 @@ CxPolicy[result] { } } -# REGLA 4: Modo incorrecto en google_container_node_pool +# RULE 4: Incorrect mode in google_container_node_pool CxPolicy[result] { doc := input.document[i] resource := doc.resource.google_container_node_pool[name] diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/README.md b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/README.md index 0501cd7724e..7648709eada 100644 --- a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/README.md +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/README.md @@ -1,52 +1,52 @@ -# Regla KICS: GKE Sandbox (gVisor) Disabled - -## Descripción General - -Esta regla de severidad **BAJA** verifica si los pools de nodos de GKE tienen habilitado **GKE Sandbox (gVisor)** para un aislamiento reforzado. - -GKE Sandbox utiliza **gVisor**, un kernel de espacio de usuario que proporciona una barrera de seguridad adicional entre las aplicaciones y el kernel del host. Al interceptar y filtrar las llamadas al sistema, gVisor mitiga el riesgo de ataques de escape de contenedor, donde un proceso malicioso intenta comprometer el nodo subyacente. Aunque gVisor introduce un ligero overhead de rendimiento, es una **Configuración Insegura** omitirlo en entornos que ejecutan código no confiable o aplicaciones multi-tenant. - -## Lógica de la Regla - -La política audita los recursos `google_container_cluster` y `google_container_node_pool`: -1. **Omisión del Bloque:** Detecta si `sandbox_config` no está presente en el `node_config`. -2. **Tipo Incorrecto:** Verifica que el `sandbox_type` sea explícitamente `"gvisor"`. - -## Casos de Fallo Detectados - ---- - -### Caso 1: Sandbox no configurado en Clúster -* **Descripción:** Los nodos predeterminados del clúster no utilizan el aislamiento de gVisor. -* **Ubicación de la Alerta:** Atributo `node_config`. - -### Caso 2: Sandbox no configurado en Node Pool -* **Descripción:** Se ha creado un pool de nodos adicional que carece de protección de Sandbox. -* **Ubicación de la Alerta:** Atributo `node_config`. - -### Caso 3: Tipo de Sandbox Inseguro -* **Descripción:** Se define el bloque pero se utiliza un valor distinto a `gvisor`, lo que desactiva la protección buscada. -* **Ubicación de la Alerta:** Atributo `sandbox_type`. - -## Recurso Involucrado - -* `google_container_cluster` -* `google_container_node_pool` - -## Solución - -Habilite gVisor asegurándose de usar el tipo de imagen compatible `COS_CONTAINERD`. - -```terraform -resource "google_container_node_pool" "secure_pool" { - name = "untrusted-code-pool" - cluster = google_container_cluster.primary.name - - node_config { - image_type = "COS_CONTAINERD" - - sandbox_config { - sandbox_type = "gvisor" - } - } -} \ No newline at end of file +# KICS Rule: GKE Sandbox (gVisor) Disabled + +## Overview + +This **LOW** severity rule verifies whether GKE node pools have **GKE Sandbox (gVisor)** enabled for enhanced isolation. + +GKE Sandbox uses **gVisor**, a user-space kernel that provides an additional security barrier between applications and the host kernel. By intercepting and filtering system calls, gVisor mitigates the risk of container escape attacks, where a malicious process attempts to compromise the underlying node. Although gVisor introduces a slight performance overhead, omitting it in environments that run untrusted code or multi-tenant applications is an **Insecure Configuration**. + +## Rule Logic + +The policy audits the `google_container_cluster` and `google_container_node_pool` resources: +1. **Block Omission:** Detects if `sandbox_config` is not present in `node_config`. +2. **Incorrect Type:** Verifies that `sandbox_type` is explicitly `"gvisor"`. + +## Detected Failure Cases + +--- + +### Case 1: Sandbox Not Configured in Cluster +* **Description:** The cluster's default nodes do not use gVisor isolation. +* **Alert Location:** `node_config` attribute. + +### Case 2: Sandbox Not Configured in Node Pool +* **Description:** An additional node pool has been created that lacks Sandbox protection. +* **Alert Location:** `node_config` attribute. + +### Case 3: Insecure Sandbox Type +* **Description:** The block is defined but a value other than `gvisor` is used, disabling the intended protection. +* **Alert Location:** `sandbox_type` attribute. + +## Resources Involved + +* `google_container_cluster` +* `google_container_node_pool` + +## Solution + +Enable gVisor ensuring the compatible `COS_CONTAINERD` image type is used. + +```terraform +resource "google_container_node_pool" "secure_pool" { + name = "untrusted-code-pool" + cluster = google_container_cluster.primary.name + + node_config { + image_type = "COS_CONTAINERD" + + sandbox_config { + sandbox_type = "gvisor" + } + } +} diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego index dce3885c859..e37255d0743 100644 --- a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: Bloque 'sandbox_config' ausente en google_container_cluster. +# RULE 1: 'sandbox_config' block missing in google_container_cluster. CxPolicy[result] { doc := input.document[i] resource := doc.resource.google_container_cluster[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: Bloque 'sandbox_config' ausente en google_container_node_pool. +# RULE 2: 'sandbox_config' block missing in google_container_node_pool. CxPolicy[result] { doc := input.document[i] resource := doc.resource.google_container_node_pool[name] @@ -38,7 +38,7 @@ CxPolicy[result] { } } -# REGLA 3: sandbox_type incorrecto en google_container_cluster. +# RULE 3: Incorrect sandbox_type in google_container_cluster. CxPolicy[result] { doc := input.document[i] resource := doc.resource.google_container_cluster[name] @@ -56,7 +56,7 @@ CxPolicy[result] { } } -# REGLA 4: sandbox_type incorrecto en google_container_node_pool. +# RULE 4: Incorrect sandbox_type in google_container_node_pool. CxPolicy[result] { doc := input.document[i] resource := doc.resource.google_container_node_pool[name] diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/README.md b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/README.md index 499f0c0645d..88394f37d3c 100644 --- a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/README.md +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/README.md @@ -1,50 +1,50 @@ -# Regla KICS: GKE Secrets Not Encrypted with CMEK - -## Descripción General - -Esta regla de severidad **ALTA** verifica que los clústeres de GKE tengan habilitado el cifrado de secretos en la capa de aplicación mediante una clave de **Cloud KMS** gestionada por el cliente (**CMEK**). - -Por defecto, GKE cifra los datos en reposo a nivel de disco, pero los secretos de Kubernetes almacenados en la base de datos `etcd` requieren una capa de protección adicional. Al habilitar esta función, GKE utiliza una clave de cifrado de sobres (envelope encryption) donde una Clave de Cifrado de Datos (DEK) cifra el secreto, y dicha DEK es cifrada por una Clave de Cifrado de Claves (KEK) alojada en Cloud KMS. Esto permite que el cliente tenga soberanía absoluta sobre sus secretos, pudiendo revocar el acceso a los mismos instantáneamente inhabilitando la clave en KMS. - -## Lógica de la Regla - -La política audita el recurso `google_container_cluster` evaluando tres fallos de seguridad: -1. **Omisión:** No se define el bloque `database_encryption`. -2. **Desactivación:** El estado de cifrado se establece explícitamente en `DECRYPTED`. -3. **Configuración Incompleta:** Se activa el cifrado pero no se proporciona el identificador de la clave (`key_name`). - -## Casos de Fallo Detectados - ---- - -### Caso 1: Configuración de Cifrado Ausente -* **Descripción:** El clúster se aprovisiona sin la capa de protección para secretos en etcd. -* **Ubicación de la Alerta:** Bloque del recurso `google_container_cluster`. - -### Caso 2: Cifrado Deshabilitado -* **Descripción:** Se configura el bloque pero el estado se marca como no cifrado. -* **Ubicación de la Alerta:** Atributo `state` dentro de `database_encryption`. - -### Caso 3: Clave KMS Faltante -* **Descripción:** Se intenta cifrar pero no se referencia ninguna clave válida de Cloud KMS. -* **Ubicación de la Alerta:** Atributo `key_name` dentro de `database_encryption`. - -## Recurso Involucrado - -* `google_container_cluster` - -## Solución - -Configure el bloque `database_encryption` con el estado `ENCRYPTED` y asigne el recurso de clave correspondiente. - -```terraform -resource "google_container_cluster" "secure_cluster" { - name = "production-cluster" - location = "us-central1" - - # Solución técnica - database_encryption { - state = "ENCRYPTED" - key_name = "projects/my-project/locations/global/keyRings/my-ring/cryptoKeys/my-key" - } -} \ No newline at end of file +# KICS Rule: GKE Secrets Not Encrypted with CMEK + +## Overview + +This **HIGH** severity rule verifies that GKE clusters have application-layer secret encryption enabled using a customer-managed **Cloud KMS** key (**CMEK**). + +By default, GKE encrypts data at rest at the disk level, but Kubernetes secrets stored in the `etcd` database require an additional layer of protection. By enabling this feature, GKE uses envelope encryption where a Data Encryption Key (DEK) encrypts the secret, and that DEK is encrypted by a Key Encryption Key (KEK) hosted in Cloud KMS. This allows the customer to have absolute sovereignty over their secrets, being able to revoke access to them instantly by disabling the key in KMS. + +## Rule Logic + +The policy audits the `google_container_cluster` resource by evaluating three security failures: +1. **Omission:** The `database_encryption` block is not defined. +2. **Disabling:** The encryption state is explicitly set to `DECRYPTED`. +3. **Incomplete Configuration:** Encryption is activated but the key identifier (`key_name`) is not provided. + +## Detected Failure Cases + +--- + +### Case 1: Missing Encryption Configuration +* **Description:** The cluster is provisioned without the protection layer for secrets in etcd. +* **Alert Location:** `google_container_cluster` resource block. + +### Case 2: Encryption Disabled +* **Description:** The block is configured but the state is marked as unencrypted. +* **Alert Location:** `state` attribute within `database_encryption`. + +### Case 3: Missing KMS Key +* **Description:** Encryption is attempted but no valid Cloud KMS key is referenced. +* **Alert Location:** `key_name` attribute within `database_encryption`. + +## Resource Involved + +* `google_container_cluster` + +## Solution + +Configure the `database_encryption` block with the `ENCRYPTED` state and assign the corresponding key resource. + +```terraform +resource "google_container_cluster" "secure_cluster" { + name = "production-cluster" + location = "us-central1" + + # Technical solution + database_encryption { + state = "ENCRYPTED" + key_name = "projects/my-project/locations/global/keyRings/my-ring/cryptoKeys/my-key" + } +} diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego index 0b7e70b2178..c7129fff397 100644 --- a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: Bloque 'database_encryption' ausente. +# RULE 1: 'database_encryption' block missing. CxPolicy[result] { doc := input.document[i] cluster := doc.resource.google_container_cluster[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: Estado de cifrado incorrecto (DECRYPTED). +# RULE 2: Incorrect encryption state (DECRYPTED). CxPolicy[result] { doc := input.document[i] cluster := doc.resource.google_container_cluster[name] @@ -38,7 +38,7 @@ CxPolicy[result] { } } -# REGLA 3: Estado ENCRYPTED pero falta el nombre de la clave (key_name). +# RULE 3: State is ENCRYPTED but key name (key_name) is missing. CxPolicy[result] { doc := input.document[i] cluster := doc.resource.google_container_cluster[name] diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/README.md b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/README.md index 3080ebf7ef9..1539f0aa785 100644 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/README.md +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/README.md @@ -1,45 +1,45 @@ -# Regla KICS: GKE Security Posture Disabled (Manual) - -## Descripción General - -Esta regla informativa (**INFO**) de **Observabilidad** verifica si el **Security Posture Dashboard** de GKE está activo en la configuración del clúster. - -El panel de postura de seguridad es una herramienta nativa de Google Cloud que escanea automáticamente las cargas de trabajo de Kubernetes en busca de errores de configuración comunes y vulnerabilidades conocidas en las imágenes de los contenedores. Proporciona recomendaciones accionables para mejorar la seguridad sin añadir complejidad operativa. Dado que la disponibilidad de esta función puede variar según el canal de versiones de GKE y el tipo de licencia (Standard vs Autopilot), esta regla alerta sobre su ausencia para permitir una verificación manual de compatibilidad. - -## Lógica de la Regla - -La política audita el recurso `google_container_cluster` identificando dos escenarios: -1. **Omisión:** El bloque `security_posture_config` no está presente en el código Terraform. -2. **Desactivación:** El bloque existe pero el parámetro `mode` se ha establecido explícitamente como `DISABLED`. - -## Casos de Fallo Detectados - ---- - -### Caso 1: Configuración de Postura Ausente -* **Descripción:** El clúster no ha habilitado el panel de control de seguridad. Se recomienda verificar si la versión de GKE permite su activación. -* **Ubicación de la Alerta:** Nivel de recurso `google_container_cluster`. - -### Caso 2: Modo de Postura Deshabilitado -* **Descripción:** Se ha configurado la postura de seguridad pero se ha desactivado mediante el valor `DISABLED`. -* **Ubicación de la Alerta:** Atributo `mode` dentro de `security_posture_config`. - -## Recurso Involucrado - -* `google_container_cluster` - -## Solución - -Habilite la postura de seguridad configurando el modo en `BASIC` o `ENTERPRISE`. - -```terraform -resource "google_container_cluster" "compliant_cluster" { - name = "monitored-cluster" - location = "us-central1" - - # Solución recomendada para observabilidad de seguridad - security_posture_config { - mode = "BASIC" - vulnerability_mode = "VULNERABILITY_BASIC" - } -} \ No newline at end of file +# KICS Rule: GKE Security Posture Disabled (Manual) + +## Overview + +This informational (**INFO**) **Observability** rule verifies whether the GKE **Security Posture Dashboard** is active in the cluster configuration. + +The security posture dashboard is a native Google Cloud tool that automatically scans Kubernetes workloads for common misconfigurations and known vulnerabilities in container images. It provides actionable recommendations to improve security without adding operational complexity. Since the availability of this feature may vary depending on the GKE version channel and license type (Standard vs Autopilot), this rule alerts on its absence to allow a manual compatibility check. + +## Rule Logic + +The policy audits the `google_container_cluster` resource identifying two scenarios: +1. **Omission:** The `security_posture_config` block is not present in the Terraform code. +2. **Disabling:** The block exists but the `mode` parameter has been explicitly set to `DISABLED`. + +## Detected Failure Cases + +--- + +### Case 1: Missing Posture Configuration +* **Description:** The cluster has not enabled the security control dashboard. It is recommended to verify whether the GKE version allows its activation. +* **Alert Location:** `google_container_cluster` resource level. + +### Case 2: Posture Mode Disabled +* **Description:** The security posture has been configured but disabled using the `DISABLED` value. +* **Alert Location:** `mode` attribute within `security_posture_config`. + +## Resource Involved + +* `google_container_cluster` + +## Solution + +Enable the security posture by setting the mode to `BASIC` or `ENTERPRISE`. + +```terraform +resource "google_container_cluster" "compliant_cluster" { + name = "monitored-cluster" + location = "us-central1" + + # Recommended solution for security observability + security_posture_config { + mode = "BASIC" + vulnerability_mode = "VULNERABILITY_BASIC" + } +} diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego index a7bade30f23..86c17a5454d 100644 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: Bloque 'security_posture_config' ausente. +# RULE 1: 'security_posture_config' block missing. CxPolicy[result] { doc := input.document[i] cluster := doc.resource.google_container_cluster[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: Bloque presente, pero 'mode' es 'DISABLED'. +# RULE 2: Block present, but 'mode' is 'DISABLED'. CxPolicy[result] { doc := input.document[i] cluster := doc.resource.google_container_cluster[name] diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/README.md b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/README.md index 62834eadff2..187d8039f8f 100644 --- a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/README.md +++ b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/README.md @@ -1,54 +1,54 @@ -# Regla KICS: GKE Workload Identity & Dedicated SA (Manual) - -## Descripción General - -Esta regla informativa (**INFO**) de **Access Control** audita la configuración de identidad para las cargas de trabajo que se ejecutan en **Google Kubernetes Engine (GKE)**. - -La mejor práctica de seguridad para que las aplicaciones de GKE accedan a los servicios de Google Cloud (como Cloud Storage o BigQuery) es utilizar **Workload Identity**. Esta funcionalidad elimina la necesidad de descargar y gestionar claves JSON de cuentas de servicio, vinculando de forma segura una Kubernetes Service Account (KSA) con una Google Service Account (GSA). - -Sin embargo, habilitar la función es solo la mitad del trabajo. Una configuración segura requiere un mapeo **1:1**; si múltiples aplicaciones comparten la misma identidad de Google, un compromiso en una de ellas otorgaría acceso lateral a los recursos de las demás. - -## Lógica de la Regla - -La política audita el recurso `google_container_cluster` en dos fases: -1. **Validación de Función:** Detecta si `workload_identity_config` está ausente, lo que obliga a los Pods a usar la identidad del nodo (riesgo alto). -2. **Auditoría de Gobernanza:** Si la función está activa, alerta al auditor para que verifique manualmente en el código que cada microservicio tiene su propia vinculación dedicada. - -## Casos de Fallo Detectados - ---- - -### Caso 1: Workload Identity Deshabilitado -* **Descripción:** El clúster carece de la infraestructura necesaria para identidades granulares. -* **Ubicación de la Alerta:** Nivel de recurso `google_container_cluster`. - -### Caso 2: Revisión de Mapeo de Identidades -* **Descripción:** La funcionalidad está activa, pero se requiere confirmar que no se están utilizando cuentas de servicio compartidas entre distintos microservicios. -* **Ubicación de la Alerta:** Bloque `workload_identity_config`. - -## Recurso Involucrado - -* `google_container_cluster` - -## Solución - -1. Habilite Workload Identity en su recurso de clúster. -2. Implemente vinculaciones granulares utilizando el rol `roles/iam.workloadIdentityUser`. - -```terraform -resource "google_container_cluster" "compliant_cluster" { - name = "secure-cluster" - location = "us-central1" - - # Habilitar la función - workload_identity_config { - workload_pool = "${var.project_id}.svc.id.goog" - } -} - -# Ejemplo de vinculación manual a verificar (Mapeo 1:1) -resource "google_service_account_iam_member" "dedicated_binding" { - service_account_id = google_service_account.app_specific_sa.name - role = "roles/iam.workloadIdentityUser" - member = "serviceAccount:${var.project_id}.svc.id.goog[namespace/ksa-name]" -} \ No newline at end of file +# KICS Rule: GKE Workload Identity & Dedicated SA (Manual) + +## Overview + +This informational (**INFO**) **Access Control** rule audits the identity configuration for workloads running in **Google Kubernetes Engine (GKE)**. + +The security best practice for GKE applications to access Google Cloud services (such as Cloud Storage or BigQuery) is to use **Workload Identity**. This functionality eliminates the need to download and manage JSON service account keys by securely binding a Kubernetes Service Account (KSA) with a Google Service Account (GSA). + +However, enabling the feature is only half the work. A secure configuration requires a **1:1** mapping; if multiple applications share the same Google identity, a compromise in one of them would grant lateral access to the resources of the others. + +## Rule Logic + +The policy audits the `google_container_cluster` resource in two phases: +1. **Feature Validation:** Detects if `workload_identity_config` is absent, which forces Pods to use the node identity (high risk). +2. **Governance Audit:** If the feature is active, it alerts the auditor to manually verify in the code that each microservice has its own dedicated binding. + +## Detected Failure Cases + +--- + +### Case 1: Workload Identity Disabled +* **Description:** The cluster lacks the infrastructure necessary for granular identities. +* **Alert Location:** `google_container_cluster` resource level. + +### Case 2: Identity Mapping Review +* **Description:** The functionality is active, but it must be confirmed that service accounts are not being shared between different microservices. +* **Alert Location:** `workload_identity_config` block. + +## Resource Involved + +* `google_container_cluster` + +## Solution + +1. Enable Workload Identity in your cluster resource. +2. Implement granular bindings using the `roles/iam.workloadIdentityUser` role. + +```terraform +resource "google_container_cluster" "compliant_cluster" { + name = "secure-cluster" + location = "us-central1" + + # Enable the feature + workload_identity_config { + workload_pool = "${var.project_id}.svc.id.goog" + } +} + +# Example of manual binding to verify (1:1 Mapping) +resource "google_service_account_iam_member" "dedicated_binding" { + service_account_id = google_service_account.app_specific_sa.name + role = "roles/iam.workloadIdentityUser" + member = "serviceAccount:${var.project_id}.svc.id.goog[namespace/ksa-name]" +} diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego index 5e1499fe702..84f83b69b72 100644 --- a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.terraform as tf_lib -# REGLA 1: Workload Identity no habilitado (Missing Attribute). +# RULE 1: Workload Identity not enabled (Missing Attribute). CxPolicy[result] { doc := input.document[i] cluster := doc.resource.google_container_cluster[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# REGLA 2: Workload Identity habilitado (Verificación Manual de Bindings). +# RULE 2: Workload Identity enabled (Manual Binding Verification). CxPolicy[result] { doc := input.document[i] cluster := doc.resource.google_container_cluster[name] diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/README.md b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/README.md index f5e5a8c4375..6f849db7f85 100644 --- a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/README.md +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/README.md @@ -1,47 +1,47 @@ -# Regla KICS: GCP HTTP(S) Load Balancer Logging Disabled - -## Descripción General - -Esta regla de severidad **MEDIA** verifica que el registro de acceso (Logging) esté habilitado en los recursos `google_compute_backend_service` de Google Cloud. - -Los Backend Services gestionan el tráfico que el balanceador de carga HTTP(S) distribuye hacia los grupos de instancias o buckets. Habilitar los logs de Cloud Armor y del balanceador permite capturar metadatos críticos de cada transacción HTTP: dirección IP de origen, protocolos, latencias de respuesta, y códigos de estado (2xx, 4xx, 5xx). Sin estos registros, la capacidad de respuesta ante incidentes de seguridad (como ataques DoS o inyecciones) y la depuración de errores de infraestructura se ven seriamente limitadas. - -## Lógica de la Regla - -La política audita el recurso `google_compute_backend_service` bajo dos criterios: -1. **Omisión:** Detecta si el bloque `log_config` no ha sido definido. -2. **Desactivación:** Detecta si el atributo `enable` dentro de `log_config` tiene el valor booleano `false`. - -## Casos de Fallo Detectados - ---- - -### Caso 1: Configuración de Logging Ausente -* **Descripción:** El servicio de backend se crea sin parámetros de registro, lo que deshabilita la telemetría de tráfico por defecto. -* **Ubicación de la Alerta:** Nivel de recurso `google_compute_backend_service`. - -### Caso 2: Logging Deshabilitado Explícitamente -* **Descripción:** Se define el bloque de configuración pero se apaga el servicio de logs. -* **Ubicación de la Alerta:** Atributo `enable` dentro de `log_config`. - -## Recurso Involucrado - -* `google_compute_backend_service` - -## Solución - -Añada el bloque `log_config` con el parámetro `enable = true`. Se recomienda un `sample_rate` de `1.0` para producción. - -```terraform -resource "google_compute_backend_service" "compliant_service" { - name = "web-backend-service" - protocol = "HTTP" - port_name = "http" - timeout_sec = 10 - - # Solución técnica - log_config { - enable = true - sample_rate = 1.0 - } -} \ No newline at end of file +# KICS Rule: GCP HTTP(S) Load Balancer Logging Disabled + +## Overview + +This **MEDIUM** severity rule verifies that access logging (Logging) is enabled in `google_compute_backend_service` resources in Google Cloud. + +Backend Services manage the traffic that the HTTP(S) load balancer distributes to instance groups or buckets. Enabling Cloud Armor and load balancer logs allows capturing critical metadata for each HTTP transaction: source IP address, protocols, response latencies, and status codes (2xx, 4xx, 5xx). Without these logs, incident response capability for security events (such as DoS attacks or injections) and debugging of infrastructure errors are severely limited. + +## Rule Logic + +The policy audits the `google_compute_backend_service` resource under two criteria: +1. **Omission:** Detects if the `log_config` block has not been defined. +2. **Disabling:** Detects if the `enable` attribute within `log_config` has the boolean value `false`. + +## Detected Failure Cases + +--- + +### Case 1: Missing Logging Configuration +* **Description:** The backend service is created without logging parameters, which disables traffic telemetry by default. +* **Alert Location:** `google_compute_backend_service` resource level. + +### Case 2: Logging Explicitly Disabled +* **Description:** The configuration block is defined but the log service is turned off. +* **Alert Location:** `enable` attribute within `log_config`. + +## Resource Involved + +* `google_compute_backend_service` + +## Solution + +Add the `log_config` block with the `enable = true` parameter. A `sample_rate` of `1.0` is recommended for production. + +```terraform +resource "google_compute_backend_service" "compliant_service" { + name = "web-backend-service" + protocol = "HTTP" + port_name = "http" + timeout_sec = 10 + + # Technical solution + log_config { + enable = true + sample_rate = 1.0 + } +} diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/README.md b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/README.md index d2cc1522d00..1c8ec66888c 100644 --- a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/README.md +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/README.md @@ -1,53 +1,53 @@ -# Regla KICS: IAP Disabled on Backend Service - -## Descripción General - -Esta regla verifica que **Identity-Aware Proxy (IAP)** esté habilitado en los recursos `google_compute_backend_service`. - -IAP es un componente de seguridad Zero Trust que intercepta las solicitudes web enviadas a tu aplicación, autentica al usuario mediante su identidad de Google y solo permite el paso de la solicitud si el usuario está autorizado. - -**Nota sobre Firewall (Manual):** -Habilitar IAP es solo el primer paso. Para cumplir completamente con la normativa de seguridad ("Permitir solo tráfico de Google"), debes configurar manualmente las reglas de firewall de tu VPC para permitir el tráfico **únicamente** desde los rangos de IP de los balanceadores de carga de Google (`130.211.0.0/22` y `35.191.0.0/16`) hacia tus instancias, bloqueando todo el tráfico directo desde Internet. - -## Lógica de la Regla - -La política audita el recurso `google_compute_backend_service`: -1. Verifica si existe el bloque de configuración `iap`. -2. Si el bloque no existe, se considera que el servicio no está protegido por identidad. -3. Verifica que, si el bloque existe, se definan las credenciales necesarias (`oauth2_client_id` y `oauth2_client_secret`). - -## Casos de Fallo Detectados - -### Caso 1: IAP Deshabilitado - -* **Descripción:** El servicio de backend se ha definido sin el bloque `iap`, lo que significa que el tráfico llega directamente (o a través del LB estándar) sin verificación de identidad previa por parte de IAP. -* **Ubicación de la Alerta:** Recurso `google_compute_backend_service`. - -### Caso 2: Cliente ID de OAuth Ausente - -* **Descripción:** El bloque `iap` está presente pero omite el `oauth2_client_id`, impidiendo la autenticación. -* **Ubicación de la Alerta:** Bloque `iap`. - -### Caso 3: Cliente Secret de OAuth Ausente - -* **Descripción:** El bloque `iap` está presente pero omite el `oauth2_client_secret`, impidiendo la autenticación. -* **Ubicación de la Alerta:** Bloque `iap`. - -## Recurso Involucrado - -* `google_compute_backend_service` - -## Solución - -Define el bloque `iap` dentro del servicio de backend e incluye las credenciales de OAuth necesarias. - -```terraform -resource "google_compute_backend_service" "secure" { - name = "iap-backend-service" - health_checks = [google_compute_health_check.default.id] - - iap { - oauth2_client_id = "abc-123.apps.googleusercontent.com" - oauth2_client_secret = "secret-key" - } -} \ No newline at end of file +# KICS Rule: IAP Disabled on Backend Service + +## Overview + +This rule verifies that **Identity-Aware Proxy (IAP)** is enabled in `google_compute_backend_service` resources. + +IAP is a Zero Trust security component that intercepts web requests sent to your application, authenticates the user via their Google identity, and only allows the request through if the user is authorized. + +**Note on Firewall (Manual):** +Enabling IAP is only the first step. To fully comply with the security policy ("Allow only Google traffic"), you must manually configure your VPC firewall rules to allow traffic **only** from Google load balancer IP ranges (`130.211.0.0/22` and `35.191.0.0/16`) to your instances, blocking all direct traffic from the Internet. + +## Rule Logic + +The policy audits the `google_compute_backend_service` resource: +1. Verifies whether the `iap` configuration block exists. +2. If the block does not exist, the service is considered unprotected by identity. +3. Verifies that, if the block exists, the required credentials (`oauth2_client_id` and `oauth2_client_secret`) are defined. + +## Detected Failure Cases + +### Case 1: IAP Disabled + +* **Description:** The backend service has been defined without the `iap` block, meaning traffic arrives directly (or through the standard LB) without prior identity verification by IAP. +* **Alert Location:** `google_compute_backend_service` resource. + +### Case 2: Missing OAuth Client ID + +* **Description:** The `iap` block is present but omits the `oauth2_client_id`, preventing authentication. +* **Alert Location:** `iap` block. + +### Case 3: Missing OAuth Client Secret + +* **Description:** The `iap` block is present but omits the `oauth2_client_secret`, preventing authentication. +* **Alert Location:** `iap` block. + +## Resource Involved + +* `google_compute_backend_service` + +## Solution + +Define the `iap` block within the backend service and include the required OAuth credentials. + +```terraform +resource "google_compute_backend_service" "secure" { + name = "iap-backend-service" + health_checks = [google_compute_health_check.default.id] + + iap { + oauth2_client_id = "abc-123.apps.googleusercontent.com" + oauth2_client_secret = "secret-key" + } +} diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/README.md b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/README.md index ccb1f2e6d79..d9596f65279 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/README.md +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/README.md @@ -1,40 +1,40 @@ -# Regla KICS: Cloud SQL PostgreSQL log_error_verbosity is Verbose - -## Descripción General - -Esta regla verifica la configuración del flag de base de datos `log_error_verbosity` en instancias de **Google Cloud SQL (PostgreSQL)**. - -Este parámetro controla la cantidad de detalles que se escriben en el registro de errores del servidor. El nivel `verbose` incluye información interna como código fuente y números de línea, lo cual no es recomendado para entornos de producción por motivos de seguridad y rendimiento. - -## Lógica de la Regla - -La política inspecciona el recurso `google_sql_database_instance`: -1. Verifica si la versión de la base de datos contiene "POSTGRES". -2. Normaliza el bloque `settings.database_flags` para procesar correctamente tanto configuraciones con un único flag como con múltiples. -3. Si encuentra un flag llamado `log_error_verbosity` con el valor `verbose`, genera una alerta. - -## Casos de Fallo Detectados - -### Caso 1: Verbosity Insegura - -* **Descripción:** El flag está explícitamente configurado como `verbose`. -* **Ubicación de la Alerta:** Bloque `database_flags`. - -## Recurso Involucrado - -* `google_sql_database_instance` - -## Solución - -Establece el valor en `default`, `terse` o elimina el flag. - -```terraform -resource "google_sql_database_instance" "secure" { - database_version = "POSTGRES_14" - settings { - database_flags { - name = "log_error_verbosity" - value = "default" - } - } -} \ No newline at end of file +# KICS Rule: Cloud SQL PostgreSQL log_error_verbosity is Verbose + +## Overview + +This rule verifies the configuration of the `log_error_verbosity` database flag in **Google Cloud SQL (PostgreSQL)** instances. + +This parameter controls the amount of detail written to the server error log. The `verbose` level includes internal information such as source code and line numbers, which is not recommended for production environments for security and performance reasons. + +## Rule Logic + +The policy inspects the `google_sql_database_instance` resource: +1. Verifies if the database version contains "POSTGRES". +2. Normalizes the `settings.database_flags` block to correctly process configurations with both single and multiple flags. +3. If it finds a flag named `log_error_verbosity` with the value `verbose`, it generates an alert. + +## Detected Failure Cases + +### Case 1: Insecure Verbosity + +* **Description:** The flag is explicitly configured as `verbose`. +* **Alert Location:** `database_flags` block. + +## Resource Involved + +* `google_sql_database_instance` + +## Solution + +Set the value to `default`, `terse`, or remove the flag. + +```terraform +resource "google_sql_database_instance" "secure" { + database_version = "POSTGRES_14" + settings { + database_flags { + name = "log_error_verbosity" + value = "default" + } + } +} diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/README.md b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/README.md index 25aed51b502..3e6b362bca9 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/README.md +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/README.md @@ -1,51 +1,51 @@ -# Regla KICS: Cloud SQL PostgreSQL log_statement Improperly Set - -## Descripción General - -Esta regla verifica la configuración del flag `log_statement` en instancias de **Google Cloud SQL (PostgreSQL)**. - -Este parámetro controla qué sentencias SQL se registran en los logs del servidor: -* **`none`:** No registra ninguna sentencia (Default). -* **`ddl`:** Registra sentencias de definición de datos (CREATE, ALTER, DROP). Recomendado por CIS Benchmark como línea base. -* **`mod`:** Registra DDL y sentencias de modificación de datos (INSERT, UPDATE, DELETE). -* **`all`:** Registra todas las sentencias. - -Para cumplir con normativas de auditoría y seguridad, se debe configurar al menos en `ddl` para rastrear cambios estructurales en la base de datos que podrían comprometer la integridad de la misma. - -## Lógica de la Regla - -La política evalúa el recurso `google_sql_database_instance` (PostgreSQL): -1. **Flag Ausente:** Si `log_statement` no se encuentra dentro de la lista de flags configurados, falla (ya que el valor por defecto de PostgreSQL es insuficiente para auditoría). -2. **Flag Incorrecto:** Si `log_statement` está presente pero su valor es explícitamente `none`, falla. - -## Casos de Fallo Detectados - -### Caso 1: Configuración Ausente -* **Descripción:** No se ha definido el flag, por lo que la base de datos no está auditando sentencias críticas. -* **Ubicación de la Alerta:** Bloque `database_flags`. - -### Caso 2: Auditoría Deshabilitada Explícitamente -* **Descripción:** El flag está configurado con el valor `none`, desactivando el registro de sentencias. -* **Ubicación de la Alerta:** Bloque `database_flags`. - -## Recurso Involucrado - -* `google_sql_database_instance` - -## Solución - -Establezca el valor del flag `log_statement` en `ddl` (mínimo recomendado para auditoría), `mod` o `all`. - -```terraform -resource "google_sql_database_instance" "secure" { - name = "secure-postgresql" - database_version = "POSTGRES_14" - region = "us-central1" - - settings { - database_flags { - name = "log_statement" - value = "ddl" - } - } -} \ No newline at end of file +# KICS Rule: Cloud SQL PostgreSQL log_statement Improperly Set + +## Overview + +This rule verifies the configuration of the `log_statement` flag in **Google Cloud SQL (PostgreSQL)** instances. + +This parameter controls which SQL statements are logged in the server logs: +* **`none`:** Does not log any statements (Default). +* **`ddl`:** Logs data definition statements (CREATE, ALTER, DROP). Recommended by CIS Benchmark as a baseline. +* **`mod`:** Logs DDL and data modification statements (INSERT, UPDATE, DELETE). +* **`all`:** Logs all statements. + +To comply with audit and security regulations, it must be configured to at least `ddl` to track structural changes in the database that could compromise its integrity. + +## Rule Logic + +The policy evaluates the `google_sql_database_instance` resource (PostgreSQL): +1. **Missing Flag:** If `log_statement` is not found within the list of configured flags, it fails (since PostgreSQL's default value is insufficient for auditing). +2. **Incorrect Flag:** If `log_statement` is present but its value is explicitly `none`, it fails. + +## Detected Failure Cases + +### Case 1: Missing Configuration +* **Description:** The flag has not been defined, so the database is not auditing critical statements. +* **Alert Location:** `database_flags` block. + +### Case 2: Auditing Explicitly Disabled +* **Description:** The flag is configured with the value `none`, disabling statement logging. +* **Alert Location:** `database_flags` block. + +## Resource Involved + +* `google_sql_database_instance` + +## Solution + +Set the value of the `log_statement` flag to `ddl` (minimum recommended for auditing), `mod`, or `all`. + +```terraform +resource "google_sql_database_instance" "secure" { + name = "secure-postgresql" + database_version = "POSTGRES_14" + region = "us-central1" + + settings { + database_flags { + name = "log_statement" + value = "ddl" + } + } +} diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego index 8cef3c00b9d..0abb99d85a2 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego @@ -10,7 +10,7 @@ has_log_statement(flags_list) { flag.name == "log_statement" } -# REGLA 1: El flag 'log_statement' no está definido (Ausente). +# RULE 1: The 'log_statement' flag is not defined (Missing). CxPolicy[result] { doc := input.document[i] resource := doc.resource.google_sql_database_instance[name] @@ -31,7 +31,7 @@ CxPolicy[result] { } } -# REGLA 2: El flag 'log_statement' existe pero está en 'none'. +# RULE 2: The 'log_statement' flag exists but is set to 'none'. CxPolicy[result] { doc := input.document[i] resource := doc.resource.google_sql_database_instance[name] From d2adff09324178edaeed6b7259bda771fa317cf9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:01 +0100 Subject: [PATCH 006/900] fix(metadata): strip CWE- prefix from cwe field in azure_app_service_application_insights_not_configured --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json index afe786dd933..2b34403066f 100644 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "721c26ff", "cloudProvider": "azure", - "cwe": "CWE-778", + "cwe": "778", "riskScore": "5.0" } \ No newline at end of file From 0678d06fb9a2b49e32b27276f6cbada9dcddced5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:02 +0100 Subject: [PATCH 007/900] fix(metadata): strip CWE- prefix from cwe field in azure_app_service_http_logs_disabled --- .../azure/azure_app_service_http_logs_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json index 95eaf2da695..84ea655c11b 100644 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "72eb3dd8", "cloudProvider": "azure", - "cwe": "CWE-778", + "cwe": "778", "riskScore": "5.0" } \ No newline at end of file From 67c01d696dfb720c78078f93a8defa37c0f99d30 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:04 +0100 Subject: [PATCH 008/900] fix(metadata): strip CWE- prefix from cwe field in azure_backup_vault_cmk_encryption_disabled --- .../azure_backup_vault_cmk_encryption_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json index de557efe53d..bf862b4b77d 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "bf4474a7", "cloudProvider": "azure", - "cwe": "CWE-326", + "cwe": "326", "riskScore": "5.0" } \ No newline at end of file From 3987690f4d5396e829404be03a34fc452ec7755d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:05 +0100 Subject: [PATCH 009/900] fix(metadata): strip CWE- prefix from cwe field in azure_backup_vault_cross_region_restore_disabled --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json index 2dc65346e16..e61bf9b8384 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "0117fb32", "cloudProvider": "azure", - "cwe": "CWE-668", + "cwe": "668", "riskScore": "5.0" } \ No newline at end of file From ca09838f5f44c73fa00cdc5720974175416fe14a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:07 +0100 Subject: [PATCH 010/900] fix(metadata): strip CWE- prefix from cwe field in azure_backup_vault_infrastructure_encryption_disabled --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json index 72af6f2ffac..fd5744a28c5 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "f7bf03d5", "cloudProvider": "azure", - "cwe": "CWE-312", + "cwe": "312", "riskScore": "5.0" } \ No newline at end of file From 889e161d92cda3f679b8e5c3d91815f9d5943ba8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:08 +0100 Subject: [PATCH 011/900] fix(metadata): strip CWE- prefix from cwe field in azure_bastion_host_missing --- .../terraform/azure/azure_bastion_host_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json b/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json index ca98958d416..682ecf082ad 100644 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "a3e941c5", "cloudProvider": "azure", - "cwe": "CWE-284", + "cwe": "284", "riskScore": "5.0" } \ No newline at end of file From a6a4bb6e0a7d3ef2dc9b5f09516eb85f95c91a33 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:10 +0100 Subject: [PATCH 012/900] fix(metadata): strip CWE- prefix from cwe field in azure_defender_easm_enabled_manual --- .../azure/azure_defender_easm_enabled_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json index 637929c90d2..838e3d80dd8 100644 --- a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "b9f8511b", "cloudProvider": "azure", - "cwe": "CWE-778", + "cwe": "778", "riskScore": "0.0" } \ No newline at end of file From bb90ba4dea5ba89c6db38e403deabfafcc59508b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:11 +0100 Subject: [PATCH 013/900] fix(metadata): strip CWE- prefix from cwe field in azure_elastic_san_public_access_enabled --- .../azure/azure_elastic_san_public_access_enabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json index e5b0c20030c..a18482ec569 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/elastic_san#public_network_access_enabled", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-284", + "cwe": "284", "descriptionID": "660863a5", "riskScore": "9.0" } \ No newline at end of file From e81f1edaccb3ba370a48bd733c5948a1764b4f95 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:12 +0100 Subject: [PATCH 014/900] fix(metadata): strip CWE- prefix from cwe field in azure_elastic_san_volume_group_cmk_encryption_disabled --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json index b0395ce911a..9fa8530f2f4 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/elastic_san_volume_group#encryption_type", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-326", + "cwe": "326", "descriptionID": "3b101ad5", "riskScore": "5.0" } \ No newline at end of file From 295e9754b6965a74707c1acbd81b170502da94dc Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:14 +0100 Subject: [PATCH 015/900] fix(metadata): strip CWE- prefix from cwe field in azure_iot_hub_defender_disabled --- .../azure/azure_iot_hub_defender_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json index 9ab57e0d2f8..e8293373172 100644 --- a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/iot_security_solution", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-693", + "cwe": "693", "descriptionID": "13be738b", "riskScore": "5.0" } \ No newline at end of file From 02daa48ea2003c071a21b3079ec32244a4bdd103 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:15 +0100 Subject: [PATCH 016/900] fix(metadata): strip CWE- prefix from cwe field in azure_key_vault_key_rotation_disabled --- .../azure/azure_key_vault_key_rotation_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json index cfe4588462c..45f4c16aa87 100644 --- a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key#rotation_policy", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-320", + "cwe": "320", "descriptionID": "ca1ffce5", "riskScore": "5.0" } \ No newline at end of file From 26a770de7736a9a2bf97caaf046489bd54422d1a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:16 +0100 Subject: [PATCH 017/900] fix(metadata): strip CWE- prefix from cwe field in azure_managed_lustre_cmk_encryption_disabled --- .../azure_managed_lustre_cmk_encryption_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json index 9b364bf8e86..3d59a0fd785 100644 --- a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/managed_lustre_file_system#key_encryption_key", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-326", + "cwe": "326", "descriptionID": "7fc653e2", "riskScore": "5.0" } \ No newline at end of file From 406683cc7c38e4c18ef2f63c6a2a308588b9c97d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:17 +0100 Subject: [PATCH 018/900] fix(metadata): strip CWE- prefix from cwe field in azure_mysql_audit_log_enabled_manual --- .../azure/azure_mysql_audit_log_enabled_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json index d385f664b47..c2126b038cc 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://learn.microsoft.com/en-us/azure/mysql/single-server/concepts-audit-logs", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-778", + "cwe": "778", "descriptionID": "8d8ac482", "riskScore": "0.0" } \ No newline at end of file From 5dea53cf47944b2557d42ea2cc4a68b692cadd79 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:18 +0100 Subject: [PATCH 019/900] fix(metadata): strip CWE- prefix from cwe field in azure_mysql_audit_log_events_connection_manual --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json index 5c03bdb8c92..700d29e52fd 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://learn.microsoft.com/en-us/azure/mysql/single-server/concepts-audit-logs", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-778", + "cwe": "778", "descriptionID": "fe65cd89", "riskScore": "0.0" } \ No newline at end of file From 8c44504885dbf79a2d3ae4c06bea1094139c7545 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:20 +0100 Subject: [PATCH 020/900] fix(metadata): strip CWE- prefix from cwe field in azure_netapp_account_cmk_encryption_disabled --- .../azure_netapp_account_cmk_encryption_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json index 3a9cb5216a0..ca65c5c543c 100644 --- a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/netapp_account_encryption", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-326", + "cwe": "326", "descriptionID": "8bed44b5", "riskScore": "5.0" } \ No newline at end of file From 48bb56dd926fe38329cfd4ac43a508767398913e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:21 +0100 Subject: [PATCH 021/900] fix(metadata): strip CWE- prefix from cwe field in azure_paas_private_endpoint_missing --- .../azure/azure_paas_private_endpoint_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json index 323e9a36184..4347d7b85fc 100644 --- a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-200", + "cwe": "200", "descriptionID": "dda11a20", "riskScore": "5.0" } \ No newline at end of file From 82ff00439502e55b9223971ab34f349ec75fe8f6 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:22 +0100 Subject: [PATCH 022/900] fix(metadata): strip CWE- prefix from cwe field in azure_production_workload_basic_consumption_sku --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json index bc8edc09dec..53dd62c61f8 100644 --- a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://azure.microsoft.com/en-us/pricing/details/app-service/linux/", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-1038", + "cwe": "1038", "descriptionID": "bd3a6fc3", "riskScore": "2.0" } \ No newline at end of file From 56530e772304bcb59361a6b8ef2e80fc631893fc Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:23 +0100 Subject: [PATCH 023/900] fix(metadata): strip CWE- prefix from cwe field in azure_recovery_services_vault_cmk_encryption_disabled --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json index 5c419b027ff..20eec170567 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/recovery_services_vault#encryption", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-326", + "cwe": "326", "descriptionID": "9436d439", "riskScore": "5.0" } \ No newline at end of file From e07deeee9ce8b55c51d3fa8290a676ccc5f5c6ee Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:25 +0100 Subject: [PATCH 024/900] fix(metadata): strip CWE- prefix from cwe field in azure_recovery_services_vault_cross_region_restore_disabled --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json index a22b92d63c6..68fd34a1b85 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/recovery_services_vault#cross_region_restore_enabled", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-668", + "cwe": "668", "descriptionID": "b7b0bc16", "riskScore": "5.0" } \ No newline at end of file From eeaef97f79513d38d3ac51121a5a586789a73431 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:26 +0100 Subject: [PATCH 025/900] fix(metadata): strip CWE- prefix from cwe field in azure_recovery_services_vault_infrastructure_encryption_disabled --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json index b8b0f0581e1..66b64c3bd8d 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/recovery_services_vault#infrastructure_encryption_enabled", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-312", + "cwe": "312", "descriptionID": "95e32d9c", "riskScore": "5.0" } \ No newline at end of file From d7c7a24b8b1dd417eee44a2fc73b4fe0f25ad854 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:27 +0100 Subject: [PATCH 026/900] fix(metadata): strip CWE- prefix from cwe field in azure_sql_server_tde_cmk_disabled --- .../azure/azure_sql_server_tde_cmk_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json index 7af9efd6682..c21b8f8b1e5 100644 --- a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mssql_server_transparent_data_encryption", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-326", + "cwe": "326", "descriptionID": "745e82b3", "riskScore": "5.0" } \ No newline at end of file From a18dc43501e195e6bbc8c76c49e3d93040b0cd5f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:28 +0100 Subject: [PATCH 027/900] fix(metadata): strip CWE- prefix from cwe field in azure_storage_account_geo_redundancy_disabled --- .../azure_storage_account_geo_redundancy_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json index 802722e8f3d..0851f69b599 100644 --- a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#account_replication_type", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-668", + "cwe": "668", "descriptionID": "56c748b8", "riskScore": "5.0" } \ No newline at end of file From 93ea1d197e031a5e21e3f9e552f7fff75886f382 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:30 +0100 Subject: [PATCH 028/900] fix(metadata): strip CWE- prefix from cwe field in azure_storage_account_infrastructure_encryption_disabled --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json index 80e27e741fd..e59db9b4718 100644 --- a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#infrastructure_encryption_enabled", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-312", + "cwe": "312", "descriptionID": "d02793e5", "riskScore": "5.0" } \ No newline at end of file From fa20a2c301ea42b2bcf702dd58975ec81fd7f889 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:31 +0100 Subject: [PATCH 029/900] fix(metadata): strip CWE- prefix from cwe field in azure_storage_account_read_only_lock_missing --- .../azure_storage_account_read_only_lock_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json index 47f3e578d38..29f1171ca19 100644 --- a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/management_lock", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-400", + "cwe": "400", "descriptionID": "3a716202", "riskScore": "2.0" } \ No newline at end of file From 70136e9175bb4d7d3a58a1d0b1108683b4065c45 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:32 +0100 Subject: [PATCH 030/900] fix(metadata): strip CWE- prefix from cwe field in azure_storage_account_versioning_disabled --- .../azure_storage_account_versioning_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json index 808f5d040b1..69dc2911b0e 100644 --- a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#versioning_enabled", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-226", + "cwe": "226", "descriptionID": "0f437572", "riskScore": "5.0" } \ No newline at end of file From c742e6d2d0e3fee225f9c8e9483b1356a5846649 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:33 +0100 Subject: [PATCH 031/900] fix(metadata): strip CWE- prefix from cwe field in azure_storage_blob_logging_disabled --- .../azure/azure_storage_blob_logging_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json index 1856f0d8d87..2512452d5a6 100644 --- a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#logging", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-778", + "cwe": "778", "descriptionID": "11fa88c0", "riskScore": "2.0" } \ No newline at end of file From b1c398b9e2d101802ff232644ab9432038519619 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:34 +0100 Subject: [PATCH 032/900] fix(metadata): strip CWE- prefix from cwe field in azure_storage_container_immutability_not_locked --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json index 8721a47bf2a..bacc6fa781e 100644 --- a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_container_immutability_policy#locked", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-284", + "cwe": "284", "descriptionID": "9b959753", "riskScore": "5.0" } \ No newline at end of file From bfc6b4b55ab430110ddf0b5a3e2ff068dbe5c255 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:36 +0100 Subject: [PATCH 033/900] fix(metadata): strip CWE- prefix from cwe field in azure_storage_critical_data_cmk_manual --- .../azure/azure_storage_critical_data_cmk_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json index 2fdd8d5d5f7..88381703072 100644 --- a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#customer_managed_key", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-312", + "cwe": "312", "descriptionID": "20fcb3ef", "riskScore": "0.0" } \ No newline at end of file From 5553de15b6f5d8553546bad899ab8168d3e708a6 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:37 +0100 Subject: [PATCH 034/900] fix(metadata): strip CWE- prefix from cwe field in azure_storage_queue_logging_disabled --- .../azure/azure_storage_queue_logging_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json index 6a397c44d81..ddc7f545aaf 100644 --- a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#logging", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-778", + "cwe": "778", "descriptionID": "cddbdd74", "riskScore": "2.0" } \ No newline at end of file From 6d60c8990dc7799e60c99fd3f1684cfe97d722ee Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:38 +0100 Subject: [PATCH 035/900] fix(metadata): strip CWE- prefix from cwe field in azure_storage_table_logging_disabled --- .../azure/azure_storage_table_logging_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json index 0a4ecadcbdc..c92fc2276cd 100644 --- a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#logging", "platform": "Terraform", "cloudProvider": "azure", - "cwe": "CWE-778", + "cwe": "778", "descriptionID": "0d29e3cf", "riskScore": "2.0" } \ No newline at end of file From 0d47fa06e2c47b565ba66a81fb18b8debeee9970 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:40 +0100 Subject: [PATCH 036/900] fix(metadata): strip CWE- prefix from cwe field in gcp_access_approval_disabled --- .../terraform/gcp/gcp_access_approval_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json index ed307e448eb..c8fd4d884be 100644 --- a/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "d7df9989", "cloudProvider": "gcp", - "cwe": "CWE-284", + "cwe": "284", "riskScore": "5.0" } \ No newline at end of file From 015621d1571b2e88bd41b94ef156ab7407429dd4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:41 +0100 Subject: [PATCH 037/900] fix(metadata): strip CWE- prefix from cwe field in gcp_api_key_api_targets_missing --- .../terraform/gcp/gcp_api_key_api_targets_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json index f7d03e3db5d..52efef95070 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "8097afd6", "cloudProvider": "gcp", - "cwe": "CWE-284", + "cwe": "284", "riskScore": "5.0" } \ No newline at end of file From cb2fd84841f733f907983385bc9cff4729aaa6a1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:42 +0100 Subject: [PATCH 038/900] fix(metadata): strip CWE- prefix from cwe field in gcp_api_key_restrictions_manual --- .../terraform/gcp/gcp_api_key_restrictions_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json index 0e1d85897c0..646a76655ad 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "7b3ba800", "cloudProvider": "gcp", - "cwe": "CWE-284", + "cwe": "284", "riskScore": "0.0" } \ No newline at end of file From a3a94a260157c27df5a3f6227f33e7de21b91a44 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:44 +0100 Subject: [PATCH 039/900] fix(metadata): strip CWE- prefix from cwe field in gcp_app_engine_https_enforcement_manual --- .../gcp/gcp_app_engine_https_enforcement_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json index 71665ae005d..d386627ecae 100644 --- a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "52b7bc15", "cloudProvider": "gcp", - "cwe": "CWE-319", + "cwe": "319", "riskScore": "0.0" } \ No newline at end of file From b3869bb878c223d6c621b30b7d25ca6fb4eddbff Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:45 +0100 Subject: [PATCH 040/900] fix(metadata): strip CWE- prefix from cwe field in gcp_compute_logging_service_disabled --- .../gcp/gcp_compute_logging_service_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json index e61fd761d2f..c3eb4755785 100644 --- a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "ccefc589", "cloudProvider": "gcp", - "cwe": "CWE-778", + "cwe": "778", "riskScore": "5.0" } \ No newline at end of file From ebe7bd1142559b87b6a68a065923d777cbb7626f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:46 +0100 Subject: [PATCH 041/900] fix(metadata): strip CWE- prefix from cwe field in gcp_gke_default_service_account_used --- .../gcp/gcp_gke_default_service_account_used/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json index 1e34cb0e1c0..a173a5838bb 100644 --- a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "8ef3f681", "cloudProvider": "gcp", - "cwe": "CWE-276", + "cwe": "276", "riskScore": "9.0" } \ No newline at end of file From 26f31eff8dca964a2b9051ea0ccb7f3fdefd380e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:47 +0100 Subject: [PATCH 042/900] fix(metadata): strip CWE- prefix from cwe field in gcp_gke_image_vulnerability_scanning_disabled --- .../gcp_gke_image_vulnerability_scanning_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json index 98d0c94186c..440389df232 100644 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "30b5b4bb", "cloudProvider": "gcp", - "cwe": "CWE-1395", + "cwe": "1395", "riskScore": "9.0" } \ No newline at end of file From 507f8f2acea7b677a7b7d346aee48cf7ac7901d1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:49 +0100 Subject: [PATCH 043/900] fix(metadata): strip CWE- prefix from cwe field in gcp_gke_manual_iam_check --- .../terraform/gcp/gcp_gke_manual_iam_check/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json index b554166f1d8..9a4ed430fcb 100644 --- a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "b29ff836", "cloudProvider": "gcp", - "cwe": "CWE-276", + "cwe": "276", "riskScore": "0.0" } \ No newline at end of file From fb2d6d394905302b5ce7348fc5c4e4ffe402a459 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:50 +0100 Subject: [PATCH 044/900] fix(metadata): strip CWE- prefix from cwe field in gcp_gke_metadata_server_disabled --- .../gcp/gcp_gke_metadata_server_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json index 8d3b7f7228a..3fb6cc664fd 100644 --- a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "e858428b", "cloudProvider": "gcp", - "cwe": "CWE-284", + "cwe": "284", "riskScore": "9.0" } \ No newline at end of file From 92ae46af2c253a719ccb7a5e17bcab6866b52110 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:51 +0100 Subject: [PATCH 045/900] fix(metadata): strip CWE- prefix from cwe field in gcp_gke_sandbox_disabled --- .../terraform/gcp/gcp_gke_sandbox_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json index 775e4ae2bf4..4f9d7325c8b 100644 --- a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "6c8a93a9", "cloudProvider": "gcp", - "cwe": "CWE-1038", + "cwe": "1038", "riskScore": "3.0" } \ No newline at end of file From 7907de995d15eca196edb15f0f0ec3963d3d4e1a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:53 +0100 Subject: [PATCH 046/900] fix(metadata): strip CWE- prefix from cwe field in gcp_gke_secrets_encryption_cmek_disabled --- .../gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json index b0353ca7a29..fc76dfc2ce3 100644 --- a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "83d1c89f", "cloudProvider": "gcp", - "cwe": "CWE-312", + "cwe": "312", "riskScore": "9.0" } \ No newline at end of file From 90bf3e0c3e5fe588f2268e961b8f8aa44d22abeb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:54 +0100 Subject: [PATCH 047/900] fix(metadata): strip CWE- prefix from cwe field in gcp_gke_security_posture_manual --- .../terraform/gcp/gcp_gke_security_posture_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json index b5d56dace4c..5f3543185af 100644 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "0d688e9b", "cloudProvider": "gcp", - "cwe": "CWE-1038", + "cwe": "1038", "riskScore": "0.0" } \ No newline at end of file From e1f8eb79f7d9b39b64ecd74b870f6c2e71a26043 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:55 +0100 Subject: [PATCH 048/900] fix(metadata): strip CWE- prefix from cwe field in gcp_gke_workload_identity_manual --- .../gcp/gcp_gke_workload_identity_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json index a936faa9f6f..95436764b02 100644 --- a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "edea054b", "cloudProvider": "gcp", - "cwe": "CWE-284", + "cwe": "284", "riskScore": "0.0" } \ No newline at end of file From dc81c328b460fb54b83c6e6b56769b6f2fe0db07 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:57 +0100 Subject: [PATCH 049/900] fix(metadata): strip CWE- prefix from cwe field in gcp_http_load_balancer_logging_disabled --- .../gcp/gcp_http_load_balancer_logging_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json index 3b02d6fc606..93ec73c9933 100644 --- a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "0ef3f3f1", "cloudProvider": "gcp", - "cwe": "CWE-778", + "cwe": "778", "riskScore": "5.0" } \ No newline at end of file From 18bcfdd8fea930de008f0cfe3256f4e8503636ae Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:12:58 +0100 Subject: [PATCH 050/900] fix(metadata): strip CWE- prefix from cwe field in gcp_iap_backend_service_disabled --- .../gcp/gcp_iap_backend_service_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json index 8a52a6eb6ed..91026cd1fa1 100644 --- a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "3f1222a9", "cloudProvider": "gcp", - "cwe": "CWE-284", + "cwe": "284", "riskScore": "5.0" } \ No newline at end of file From 60ee68b0ba559ca7913f9f62f18292564e0ed170 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:00 +0100 Subject: [PATCH 051/900] fix(metadata): strip CWE- prefix from cwe field in gcp_sql_postgresql_log_error_verbosity_verbose --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json index f22e4df4ca1..7f93ca0a6ae 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "80d98d7b", "cloudProvider": "gcp", - "cwe": "CWE-532", + "cwe": "532", "riskScore": "5.0" } \ No newline at end of file From 12c717da93438d0a2788ac5d781c806e5ce19fe5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:01 +0100 Subject: [PATCH 052/900] fix(metadata): strip CWE- prefix from cwe field in gcp_sql_postgresql_log_statement_improperly_set --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json index 694b953ce2a..5ab38538ac6 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "ede2d9e4", "cloudProvider": "gcp", - "cwe": "CWE-778", + "cwe": "778", "riskScore": "5.0" } \ No newline at end of file From 92143f009875bfe58c4dad1c491d518bf85d3d02 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:02 +0100 Subject: [PATCH 053/900] fix(metadata): strip CWE- prefix from cwe field in ibm_activity_tracker_global_events_disabled --- .../ibm_activity_tracker_global_events_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json index 55ea8278a4b..c73977dba20 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "479bbdfd", "cloudProvider": "ibm", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 3.0 } \ No newline at end of file From f51d0033bc070d908907c03a83d7fe03e8c047d0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:03 +0100 Subject: [PATCH 054/900] fix(metadata): strip CWE- prefix from cwe field in ibm_activity_tracker_platform_logs_disabled --- .../ibm_activity_tracker_platform_logs_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json index 9f93f69fbc2..ba5e52bd52a 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "ccf65fe5", "cloudProvider": "ibm", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 6.0 } \ No newline at end of file From 77aa239a63f1abda5f5cf28f7887dcb20cd2a994 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:05 +0100 Subject: [PATCH 055/900] fix(metadata): strip CWE- prefix from cwe field in ibm_block_storage_customer_encryption_unified --- .../ibm_block_storage_customer_encryption_unified/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json index b6962cab19c..8e700e56478 100644 --- a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json +++ b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "56cd75da", "cloudProvider": "ibm", - "cwe": "CWE-312", + "cwe": "312", "riskScore": 0.0 } \ No newline at end of file From 40186bc2841aaf335fc43c9b50af99a4ae19ea90 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:06 +0100 Subject: [PATCH 056/900] fix(metadata): strip CWE- prefix from cwe field in ibm_certificate_manager_auto_renew_disabled --- .../ibm_certificate_manager_auto_renew_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json index 71ce8c750b8..a6bbc84bfac 100644 --- a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "6797782b", "cloudProvider": "ibm", - "cwe": "CWE-320", + "cwe": "320", "riskScore": 3.0 } \ No newline at end of file From 51ece437837420c990fd04c7db07f9c2f2396c82 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:08 +0100 Subject: [PATCH 057/900] fix(metadata): strip CWE- prefix from cwe field in ibm_cis_dns_not_proxied_manual --- .../terraform/ibm/ibm_cis_dns_not_proxied_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/metadata.json b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/metadata.json index 9227b92c430..ad4e22f476f 100644 --- a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "124e18ee", "cloudProvider": "ibm", - "cwe": "CWE-770", + "cwe": "770", "riskScore": 0.0 } \ No newline at end of file From f029d988ece11c135ef2aca031674a05e059b6e8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:09 +0100 Subject: [PATCH 058/900] fix(metadata): strip CWE- prefix from cwe field in ibm_cis_waf_enabled_manual --- .../terraform/ibm/ibm_cis_waf_enabled_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/metadata.json b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/metadata.json index dbcc6548aa0..585bbc82fcb 100644 --- a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "1e0c94f5", "cloudProvider": "ibm", - "cwe": "CWE-1021", + "cwe": "1021", "riskScore": 0.0 } \ No newline at end of file From ebacac21df499924cd7dd83abe17dfc0d4c406cc Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:10 +0100 Subject: [PATCH 059/900] fix(metadata): strip CWE- prefix from cwe field in ibm_cloudant_cmk_encryption_manual --- .../ibm/ibm_cloudant_cmk_encryption_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/metadata.json b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/metadata.json index 2e63c668243..4cf780d188f 100644 --- a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "601ca2bb", "cloudProvider": "ibm", - "cwe": "CWE-312", + "cwe": "312", "riskScore": 0.0 } \ No newline at end of file From 754126df2dc60c48fafd949e765f3d516a6cf5fe Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:12 +0100 Subject: [PATCH 060/900] fix(metadata): strip CWE- prefix from cwe field in ibm_container_cluster_entitlement_check --- .../ibm/ibm_container_cluster_entitlement_check/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/metadata.json b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/metadata.json index 36922ba0ea7..95b89185446 100644 --- a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/metadata.json +++ b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "d2fc37af", "cloudProvider": "ibm", - "cwe": "CWE-284", + "cwe": "284", "riskScore": 0.0 } \ No newline at end of file From ece9c837a507e32ea5ebff10f7bf6e022381d4e0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:13 +0100 Subject: [PATCH 061/900] fix(metadata): strip CWE- prefix from cwe field in ibm_container_registry_va_alerts_missing --- .../ibm/ibm_container_registry_va_alerts_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json index 6d1b5a772d7..83b00164611 100644 --- a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json +++ b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "92440d0d", "cloudProvider": "ibm", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 3.0 } \ No newline at end of file From e4e64458205ac2d4edf2ee3cd7888dc746809392 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:14 +0100 Subject: [PATCH 062/900] fix(metadata): strip CWE- prefix from cwe field in ibm_cos_bucket_customer_encryption_unified --- .../ibm_cos_bucket_customer_encryption_unified/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json index 663d9c51106..ae022f1e3c9 100644 --- a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json +++ b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "8f65bf01", "cloudProvider": "ibm", - "cwe": "CWE-312", + "cwe": "312", "riskScore": 0.0 } \ No newline at end of file From bd131deac406ac97181ad4bd96eadc2c2d5e0f53 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:15 +0100 Subject: [PATCH 063/900] fix(metadata): strip CWE- prefix from cwe field in ibm_database_cmk_encryption_manual --- .../ibm/ibm_database_cmk_encryption_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/metadata.json b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/metadata.json index 78ee536c83a..da99104d27e 100644 --- a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "c973475c", "cloudProvider": "ibm", - "cwe": "CWE-312", + "cwe": "312", "riskScore": 0.0 } \ No newline at end of file From fa074ab41850b54353ef1c28236e38259388277f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:17 +0100 Subject: [PATCH 064/900] fix(metadata): strip CWE- prefix from cwe field in ibm_iam_account_ip_restrictions_manual --- .../ibm/ibm_iam_account_ip_restrictions_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/metadata.json index c220420064a..e0cb5215b3a 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "61d76d70", "cloudProvider": "ibm", - "cwe": "CWE-284", + "cwe": "284", "riskScore": 0.0 } \ No newline at end of file From 06bdeab628aefb5d8ac5a52efae5595e0c6bf7bf Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:18 +0100 Subject: [PATCH 065/900] fix(metadata): strip CWE- prefix from cwe field in ibm_iam_account_mfa_disabled --- .../terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json index 5cbe9b1f843..760dee34438 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "ebaef99e", "cloudProvider": "ibm", - "cwe": "CWE-308", + "cwe": "308", "riskScore": 9.0 } \ No newline at end of file From ee6fb21b1d83c96458edd66c0c05520088ea58ac Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:19 +0100 Subject: [PATCH 066/900] fix(metadata): strip CWE- prefix from cwe field in ibm_iam_api_key_unused_manual --- .../terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json index c9c10f6d76a..d60818a7755 100644 --- a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "a2b88f1a", "cloudProvider": "ibm", - "cwe": "CWE-798", + "cwe": "798", "riskScore": 0.0 } \ No newline at end of file From ec5bbba721fe73be182c5274d1fae1dea3fbe903 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:21 +0100 Subject: [PATCH 067/900] fix(metadata): strip CWE- prefix from cwe field in ibm_iam_owner_api_key_manual --- .../terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json index b0a60a9691d..fc7fccf9f7c 100644 --- a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "dae483b9", "cloudProvider": "ibm", - "cwe": "CWE-269", + "cwe": "269", "riskScore": 0.0 } \ No newline at end of file From 09890cdad0cfaf212dc327e04d64ac9f53af4f29 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:22 +0100 Subject: [PATCH 068/900] fix(metadata): strip CWE- prefix from cwe field in ibm_iam_policy_assigned_to_user_manual --- .../ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json index 97aee910dd5..f97974148c0 100644 --- a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "d08b8443", "cloudProvider": "ibm", - "cwe": "CWE-284", + "cwe": "284", "riskScore": 0.0 } \ No newline at end of file From 87de7d515f3d998e3eae634780413e426cd847a7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:23 +0100 Subject: [PATCH 069/900] fix(metadata): strip CWE- prefix from cwe field in ibm_iam_restrict_apikey_creation_manual --- .../ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json index 8f2aba14b52..f9e4db1b9a1 100644 --- a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "30640fc8", "cloudProvider": "ibm", - "cwe": "CWE-276", + "cwe": "276", "riskScore": 0.0 } \ No newline at end of file From 6e5000991d3388dbd7d52059555ee80567e0b5df Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:25 +0100 Subject: [PATCH 070/900] fix(metadata): strip CWE- prefix from cwe field in ibm_iam_session_expiration_too_long --- .../ibm/ibm_iam_session_expiration_too_long/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json index 3cd3a3c7988..ec40a2f20b8 100644 --- a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "3d6db2d6", "cloudProvider": "ibm", - "cwe": "CWE-613", + "cwe": "613", "riskScore": 5.0 } \ No newline at end of file From 522559569079bf559552b158f3988eb447ab6266 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:26 +0100 Subject: [PATCH 071/900] fix(metadata): strip CWE- prefix from cwe field in ibm_iks_cluster_logging_disabled --- .../ibm/ibm_iks_cluster_logging_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json index 5461ea44b9c..926044c4d00 100644 --- a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "e55a0224", "cloudProvider": "ibm", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 5.0 } \ No newline at end of file From cc1a80063115f4c7d58717756f2f2ad6f9f78627 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:27 +0100 Subject: [PATCH 072/900] fix(metadata): strip CWE- prefix from cwe field in ibm_iks_cluster_monitoring_disabled --- .../ibm/ibm_iks_cluster_monitoring_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json index 5b72713ac11..d647f353b8b 100644 --- a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "51bac252", "cloudProvider": "ibm", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 5.0 } \ No newline at end of file From c98685b1d955fbd2451914d4822b282d3213edd9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:29 +0100 Subject: [PATCH 073/900] fix(metadata): strip CWE- prefix from cwe field in ibm_instance_os_disk_encryption_manual --- .../ibm/ibm_instance_os_disk_encryption_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/metadata.json b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/metadata.json index 3a961663e59..72bf60cf62c 100644 --- a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "86f1560c", "cloudProvider": "ibm", - "cwe": "CWE-312", + "cwe": "312", "riskScore": 0.0 } \ No newline at end of file From ee975276e7def7fe733ae50a481ca8ca15dcb31e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:30 +0100 Subject: [PATCH 074/900] fix(metadata): strip CWE- prefix from cwe field in ibm_kms_key_rotation_disabled --- .../terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json index be6ef0a17ba..13264914a47 100644 --- a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "cdaf415c", "cloudProvider": "ibm", - "cwe": "CWE-320", + "cwe": "320", "riskScore": 9.0 } \ No newline at end of file From c9ae53690fedebbec92580e3ec5a007402ef2a8b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:31 +0100 Subject: [PATCH 075/900] fix(metadata): strip CWE- prefix from cwe field in ibm_logdna_archiving_disabled --- .../terraform/ibm/ibm_logdna_archiving_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json index 5239adf0903..6176da424f6 100644 --- a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "54c5b041", "cloudProvider": "ibm", - "cwe": "CWE-223", + "cwe": "223", "riskScore": 5.0 } \ No newline at end of file From 5b84ccbc539c6a6fc5900eb8e87eed9781d5046f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:33 +0100 Subject: [PATCH 076/900] fix(metadata): strip CWE- prefix from cwe field in ibm_logdna_view_without_alert --- .../terraform/ibm/ibm_logdna_view_without_alert/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json index 848cfc8ebee..962f9d1ea8b 100644 --- a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json +++ b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "a5107e68", "cloudProvider": "ibm", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 1.0 } \ No newline at end of file From a9219268759487f3f00330645591db9700e8f70c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:34 +0100 Subject: [PATCH 077/900] fix(metadata): strip CWE- prefix from cwe field in oci_cloud_guard_problem_event_rule_missing --- .../oci_cloud_guard_problem_event_rule_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json index 30679dbec92..1f069ec2587 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "3ce366ab", "cloudProvider": "oci", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 3.0 } \ No newline at end of file From b057ef3c81ee625438b061ba287ce75e83912c38 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:35 +0100 Subject: [PATCH 078/900] fix(metadata): strip CWE- prefix from cwe field in oci_cloud_guard_root_compartment_disabled --- .../oci/oci_cloud_guard_root_compartment_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json index 2fe76f5d26d..60537e2b884 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "3e784705", "cloudProvider": "oci", - "cwe": "CWE-16", + "cwe": "16", "riskScore": 6.0 } \ No newline at end of file From d8da22c50490997e163e402dd3bc2f10f922d04b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:37 +0100 Subject: [PATCH 079/900] fix(metadata): strip CWE- prefix from cwe field in oci_compute_legacy_metadata_enabled --- .../oci/oci_compute_legacy_metadata_enabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json index 096fbcb75b1..9a3c40335f8 100644 --- a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "96b464dc", "cloudProvider": "oci", - "cwe": "CWE-918", + "cwe": "918", "riskScore": 3.0 } \ No newline at end of file From e7bb8a9505daed513b21eb3dc5d2c19cc1214b4f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:38 +0100 Subject: [PATCH 080/900] fix(metadata): strip CWE- prefix from cwe field in oci_compute_secure_boot_disabled --- .../oci/oci_compute_secure_boot_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json index cf5f14dbb12..597764d82b9 100644 --- a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "1f24d72d", "cloudProvider": "oci", - "cwe": "CWE-427", + "cwe": "427", "riskScore": 3.0 } \ No newline at end of file From 7810ed96f217d8da7f5534c3e593e2fc9ed42647 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:39 +0100 Subject: [PATCH 081/900] fix(metadata): strip CWE- prefix from cwe field in oci_default_tags_not_defined --- .../terraform/oci/oci_default_tags_not_defined/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json b/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json index 6fc5306fe52..e228ba1593c 100644 --- a/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json +++ b/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "4c294256", "cloudProvider": "oci", - "cwe": "CWE-16", + "cwe": "16", "riskScore": 1.0 } \ No newline at end of file From 8fbdfe1474a65289c28733c7a6a789dda3365b2c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:41 +0100 Subject: [PATCH 082/900] fix(metadata): strip CWE- prefix from cwe field in oci_iam_group_change_event_rule_missing --- .../oci/oci_iam_group_change_event_rule_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json index 3e1725b4d05..a7579bc602b 100644 --- a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "3f6ba6dd", "cloudProvider": "oci", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 3.0 } \ No newline at end of file From 283354f76d759a274471ec1913130f5234066b6c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:42 +0100 Subject: [PATCH 083/900] fix(metadata): strip CWE- prefix from cwe field in oci_iam_password_expiration_manual --- .../oci/oci_iam_password_expiration_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/metadata.json b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/metadata.json index 448d734df94..e71bdce5403 100644 --- a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "7f47496b", "cloudProvider": "oci", - "cwe": "CWE-261", + "cwe": "261", "riskScore": 0.0 } \ No newline at end of file From c20e2f03d4ed4792f8bbffaff0ff41706048e78b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:43 +0100 Subject: [PATCH 084/900] fix(metadata): strip CWE- prefix from cwe field in oci_iam_password_policy_length --- .../terraform/oci/oci_iam_password_policy_length/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json b/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json index df4b0cbef87..58a657110f4 100644 --- a/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "ef7a0923", "cloudProvider": "oci", - "cwe": "CWE-521", + "cwe": "521", "riskScore": 3.0 } \ No newline at end of file From 7869c24f76b73e9fb0c09891d89f906909fc7e51 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:45 +0100 Subject: [PATCH 085/900] fix(metadata): strip CWE- prefix from cwe field in oci_iam_password_reuse_manual --- .../terraform/oci/oci_iam_password_reuse_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/metadata.json b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/metadata.json index 9c7e71e0bdd..0112949bc71 100644 --- a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "fc42ff43", "cloudProvider": "oci", - "cwe": "CWE-261", + "cwe": "261", "riskScore": 0.0 } \ No newline at end of file From 7af35759f8f81fddda92a64626f6d0e7fcdb5c1e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:46 +0100 Subject: [PATCH 086/900] fix(metadata): strip CWE- prefix from cwe field in oci_iam_policy_change_event_rule_missing --- .../oci/oci_iam_policy_change_event_rule_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json index 2dd9f4cfdbd..b3c738001cb 100644 --- a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "a151d9a0", "cloudProvider": "oci", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 4.0 } \ No newline at end of file From 18c6fd24d18379b3cfc8a2b88d4b2607d4cb0146 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:47 +0100 Subject: [PATCH 087/900] fix(metadata): strip CWE- prefix from cwe field in oci_iam_service_admins_manual --- .../terraform/oci/oci_iam_service_admins_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_iam_service_admins_manual/metadata.json b/assets/queries/terraform/oci/oci_iam_service_admins_manual/metadata.json index ecb116d27ae..d555d9db3b4 100644 --- a/assets/queries/terraform/oci/oci_iam_service_admins_manual/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_service_admins_manual/metadata.json @@ -7,7 +7,7 @@ "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/identity_policy", "platform": "Terraform", "cloudProvider": "oci", - "cwe": "CWE-276", + "cwe": "276", "descriptionID": "0401f017", "riskScore": 0.0 } \ No newline at end of file From 38459af385ef834207af759911f2072a210ea8a7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:48 +0100 Subject: [PATCH 088/900] fix(metadata): strip CWE- prefix from cwe field in oci_iam_user_change_event_rule_missing --- .../oci/oci_iam_user_change_event_rule_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json index abb44be36ee..8bc995bedbd 100644 --- a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "b1405757", "cloudProvider": "oci", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 6.0 } \ No newline at end of file From 47157439dac4e0601eb63c07b07fe729939f52c5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:50 +0100 Subject: [PATCH 089/900] fix(metadata): strip CWE- prefix from cwe field in oci_idp_change_event_rule_missing --- .../oci/oci_idp_change_event_rule_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json index 12d91b5fcb1..5b2f34a58f8 100644 --- a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "0a077b15", "cloudProvider": "oci", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 3.0 } \ No newline at end of file From 9c7ffa95e1a37727fbeb40b0f6907236e386dbb7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:51 +0100 Subject: [PATCH 090/900] fix(metadata): strip CWE- prefix from cwe field in oci_idp_group_mapping_change_event_rule_missing --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json index cbd08451173..f846ac3c86c 100644 --- a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "1f106aa1", "cloudProvider": "oci", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 3.0 } \ No newline at end of file From 5a462755a29a7e5ca61b39c909b628d4ca579c7b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:52 +0100 Subject: [PATCH 091/900] fix(metadata): strip CWE- prefix from cwe field in oci_instance_transit_encryption --- .../terraform/oci/oci_instance_transit_encryption/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json b/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json index e5173108120..a5caa03b244 100644 --- a/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "c29ef8f7", "cloudProvider": "oci", - "cwe": "CWE-311", + "cwe": "311", "riskScore": 3.0 } \ No newline at end of file From 437d98babe2f7e109643508103ad3e19b3dd3dc8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:54 +0100 Subject: [PATCH 092/900] fix(metadata): strip CWE- prefix from cwe field in oci_local_user_authentication_event_rule_missing --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json index 94d694b39b7..e8ebe356558 100644 --- a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "e0c61731", "cloudProvider": "oci", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 6.0 } \ No newline at end of file From 9e9ad8ac5c57be63e050c873d26b93177a5a4f91 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:55 +0100 Subject: [PATCH 093/900] fix(metadata): strip CWE- prefix from cwe field in oci_network_gateway_change_event_rule_missing --- .../oci_network_gateway_change_event_rule_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json index b289b68450e..41c8e0f60c3 100644 --- a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "e3ade454", "cloudProvider": "oci", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 3.0 } \ No newline at end of file From 49d99cf7ea1a4974a2ccca4d1d88cd9bda08e8d3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:56 +0100 Subject: [PATCH 094/900] fix(metadata): strip CWE- prefix from cwe field in oci_notification_topic_without_subscription --- .../oci_notification_topic_without_subscription/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json index 17933e50ae3..39d7c4161d3 100644 --- a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "8e61709a", "cloudProvider": "oci", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 3.0 } \ No newline at end of file From 53e43acdb321c9826461db073fac5bb3744391c1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:57 +0100 Subject: [PATCH 095/900] fix(metadata): strip CWE- prefix from cwe field in oci_nsg_change_event_rule_missing --- .../oci/oci_nsg_change_event_rule_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json index f6523663741..34f43cdb6bc 100644 --- a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "a1b080a7", "cloudProvider": "oci", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 3.0 } \ No newline at end of file From 7133da1e60d48e94fb3d981f78aaa44eeece10bf Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:13:59 +0100 Subject: [PATCH 096/900] fix(metadata): strip CWE- prefix from cwe field in oci_objectstorage_bucket_logging_enabled --- .../oci/oci_objectstorage_bucket_logging_enabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json index cb41f1a3af0..b3185a237c1 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "5ecf7b51", "cloudProvider": "oci", - "cwe": "CWE-223", + "cwe": "223", "riskScore": 3.0 } \ No newline at end of file From f51533e28ff4d05379417870027b4d305caf5c1d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:14:00 +0100 Subject: [PATCH 097/900] fix(metadata): strip CWE- prefix from cwe field in oci_objectstorage_bucket_versioning_disabled --- .../oci_objectstorage_bucket_versioning_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json index 600bcac7475..d23f886b3cf 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "72b1c53c", "cloudProvider": "oci", - "cwe": "CWE-668", + "cwe": "668", "riskScore": 3.0 } \ No newline at end of file From b1998d9e3bf1021817be8e48054e4982b1ea1c17 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:14:02 +0100 Subject: [PATCH 098/900] fix(metadata): strip CWE- prefix from cwe field in oci_resource_created_in_root_compartment --- .../oci/oci_resource_created_in_root_compartment/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json index c568020e617..43b4c4ff5ad 100644 --- a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json +++ b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "eb205044", "cloudProvider": "oci", - "cwe": "CWE-284", + "cwe": "284", "riskScore": 6.0 } \ No newline at end of file From 2a9dd5be33a4eb0b24fe96313867cc1931be2e00 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:14:03 +0100 Subject: [PATCH 099/900] fix(metadata): strip CWE- prefix from cwe field in oci_route_table_change_event_rule_missing --- .../oci/oci_route_table_change_event_rule_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json index 81c3ef62cf8..19cc9e370ab 100644 --- a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "b3af1ce8", "cloudProvider": "oci", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 3.0 } \ No newline at end of file From 4c8594c8186d5124c01f501ffba41e5d753e0fac Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:14:04 +0100 Subject: [PATCH 100/900] fix(metadata): strip CWE- prefix from cwe field in oci_security_list_change_event_rule_missing --- .../oci_security_list_change_event_rule_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json index 2a6684d23b6..9582da7f342 100644 --- a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "a5dfa109", "cloudProvider": "oci", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 3.0 } \ No newline at end of file From 43a34ca7528a3d13a4dbdecfd39bb30e5a472361 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:14:06 +0100 Subject: [PATCH 101/900] fix(metadata): strip CWE- prefix from cwe field in oci_storage_admin_no_delete_manual --- .../oci/oci_storage_admin_no_delete_manual/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/metadata.json b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/metadata.json index 2ea719539c7..67d76ec4ced 100644 --- a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/metadata.json +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "8cd7b5db", "cloudProvider": "oci", - "cwe": "CWE-269", + "cwe": "269", "riskScore": 0.0 } \ No newline at end of file From 28b764a1e77c892e810b89f268a76864f34df31b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:14:07 +0100 Subject: [PATCH 102/900] fix(metadata): strip CWE- prefix from cwe field in oci_storage_cmk_encryption_unified --- .../oci/oci_storage_cmk_encryption_unified/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json index 5f63a1e8122..a35c5bab743 100644 --- a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json +++ b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "cb72ae80", "cloudProvider": "oci", - "cwe": "CWE-312", + "cwe": "312", "riskScore": 3.0 } \ No newline at end of file From c81211def04c5f6ee179795d0437af925df5a246 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:14:09 +0100 Subject: [PATCH 103/900] fix(metadata): strip CWE- prefix from cwe field in oci_vcn_change_event_rule_missing --- .../oci/oci_vcn_change_event_rule_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json index 361d6d05535..0c669cbabf4 100644 --- a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json @@ -8,6 +8,6 @@ "platform": "Terraform", "descriptionID": "419bb431", "cloudProvider": "oci", - "cwe": "CWE-778", + "cwe": "778", "riskScore": 3.0 } \ No newline at end of file From a58f1e6b949f68d8768deb227694aafcc82080dd Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:15:46 +0100 Subject: [PATCH 104/900] fix(queries): remove undocumented README.md from azure_app_service_application_insights_not_configured --- .../README.md | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/README.md diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/README.md b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/README.md deleted file mode 100644 index d8327339318..00000000000 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# KICS Rule: App Service Application Insights Not Configured - -## General Description - -This rule verifies that Azure App Service and Function Apps have **Application Insights** integration configured. - -Application Insights is an Azure Monitor feature that provides application performance management (APM) and real-time error tracking. To link an App Service with Application Insights in Terraform, `APPLICATIONINSIGHTS_CONNECTION_STRING` (recommended) or `APPINSIGHTS_INSTRUMENTATIONKEY` must be defined within the `app_settings` block. - -## Rule Logic - -The policy iterates over `azurerm_linux_web_app`, `azurerm_windows_web_app`, `azurerm_linux_function_app`, and `azurerm_windows_function_app` resources. -It checks the configuration at two levels: -1. **Absence of app_settings:** If the block is not defined. -2. **Incomplete configuration:** If the block exists but does not contain the connection keys. - -## Detected Failure Cases - -### Case 1: Missing app_settings Configuration - -* **Description:** The resource does not have the `app_settings` block defined. -* **Alert Location:** Main resource level. - -### Case 2: App Insights Keys Missing - -* **Description:** The `app_settings` block exists but does not contain `APPLICATIONINSIGHTS_CONNECTION_STRING` or `APPINSIGHTS_INSTRUMENTATIONKEY`. -* **Alert Location:** `app_settings` attribute. - -## Involved Resource - -* `azurerm_linux_web_app` -* `azurerm_windows_web_app` -* `azurerm_linux_function_app` -* `azurerm_windows_function_app` - -## Solution - -Define `APPLICATIONINSIGHTS_CONNECTION_STRING` within `app_settings`. - -```terraform -resource "azurerm_linux_web_app" "example" { - name = "example-app" - # ... - app_settings = { - "APPLICATIONINSIGHTS_CONNECTION_STRING" = azurerm_application_insights.example.connection_string - } -} From 5faf19bd70c1c670bff3f9c9a7a5f93da3e7e322 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:15:47 +0100 Subject: [PATCH 105/900] fix(queries): remove undocumented README.md from azure_app_service_http_logs_disabled --- .../README.md | 55 ------------------- 1 file changed, 55 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_app_service_http_logs_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/README.md b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/README.md deleted file mode 100644 index d3201cb2649..00000000000 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# KICS Rule: App Service HTTP Logs Disabled - -## General Description - -This rule verifies that Azure App Service resources (`azurerm_linux_web_app` and `azurerm_windows_web_app`) have HTTP logs enabled. - -HTTP logs record the web requests received by the application, including the requested URL, user agent, client IP address, and response status code. This information is essential for security auditing, regulatory compliance, and troubleshooting traffic issues. - -## Rule Logic - -The policy iterates over App Service resources and checks the configuration in two steps: -1. **Absence of Logs:** Checks whether the `logs` block exists. -2. **Absence of HTTP Logs:** If the `logs` block exists, checks that it contains the `http_logs` sub-block. - -If HTTP logging is not explicitly enabled, an alert is generated. - -## Detected Failure Cases - -### Case 1: Missing Logs Configuration - -* **Description:** The App Service resource is defined without specifying any `logs` configuration. -* **Alert Location:** Main resource level. - -### Case 2: http_logs Block Omitted - -* **Description:** The `logs` block is defined (e.g., for application logs), but HTTP traffic logs are omitted. -* **Alert Location:** `logs` block. - -## Involved Resource - -* `azurerm_linux_web_app` -* `azurerm_windows_web_app` - -## Solution - -Add the `logs` block and configure `http_logs` by defining a file system (`file_system`) or blob storage (`azure_blob_storage`). - -```terraform -resource "azurerm_linux_web_app" "example_secure" { - name = "example-linux-web-app-secure" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - service_plan_id = azurerm_service_plan.example.id - - site_config {} - - logs { - http_logs { - file_system { - retention_in_days = 7 - retention_in_mb = 35 - } - } - } -} From 47f5d1718d914266aff2885f7b0ca24db06138be Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:15:48 +0100 Subject: [PATCH 106/900] fix(queries): remove undocumented README.md from azure_backup_vault_cmk_encryption_disabled --- .../README.md | 37 ------------------- 1 file changed, 37 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/README.md deleted file mode 100644 index 2e8563a44a8..00000000000 --- a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# KICS Rule: Backup Vault CMK Encryption Disabled - -## General Description - -This rule verifies that Azure backup vaults (**Backup Vaults** from the Data Protection service) are encrypted using **Customer-Managed Keys (CMK)**. - -Using customer-managed keys provides full control over the key lifecycle (creation, rotation, and revocation) and is a common requirement in environments with high security and compliance demands. In Terraform, this is configured through a separate resource (`azurerm_data_protection_backup_vault_customer_managed_key`) that links the Vault to the key stored in a Key Vault. - -## Rule Logic - -The policy performs a relationship analysis between resources: -1. Identifies all `azurerm_data_protection_backup_vault` resources. -2. Searches for an `azurerm_data_protection_backup_vault_customer_managed_key` resource whose `data_protection_backup_vault_id` property points to the analyzed Vault. -3. Verifies that this association resource has the `key_vault_key_id` attribute defined. -4. If this linkage does not exist, an alert is generated indicating that the Vault uses platform-managed keys (default configuration). - -## Detected Failure Cases - -### Case 1: Backup Vault Without CMK - -* **Description:** The Backup Vault is defined but the customer-managed encryption key association resource is not found. -* **Alert Location:** On the `azurerm_data_protection_backup_vault` resource. - -## Involved Resource - -* `azurerm_data_protection_backup_vault` -* `azurerm_data_protection_backup_vault_customer_managed_key` - -## Solution - -Define the `azurerm_data_protection_backup_vault_customer_managed_key` association resource and link it to the Vault and the corresponding Key. - -```terraform -resource "azurerm_data_protection_backup_vault_customer_managed_key" "example" { - data_protection_backup_vault_id = azurerm_data_protection_backup_vault.example.id - key_vault_key_id = azurerm_key_vault_key.example.id -} From 854cd9c7c2a10043bc83f607a3cb336f3ff4be52 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:15:49 +0100 Subject: [PATCH 107/900] fix(queries): remove undocumented README.md from azure_backup_vault_cross_region_restore_disabled --- .../README.md | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/README.md b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/README.md deleted file mode 100644 index bbf12d0bf78..00000000000 --- a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# KICS Rule: Backup Vault Cross Region Restore Disabled - -## General Description - -This rule verifies that the **Cross Region Restore** functionality (`cross_region_restore_enabled`) is enabled on `azurerm_data_protection_backup_vault` resources. - -Cross Region Restore (CRR) allows backup data to be restored in a secondary paired Azure region (Azure Paired Region). This is essential to ensure business continuity and data recovery in the event that the primary region suffers a total outage or geographic disaster. - -**Note:** To use CRR effectively, the vault requires redundancy to be configured as `GeoRedundant`. - -## Rule Logic - -The policy evaluates the `azurerm_data_protection_backup_vault` resource under two scenarios: -1. **Missing Attribute:** If `cross_region_restore_enabled` is not explicitly defined, an alert is generated on the resource (since the default value on the platform is usually false). -2. **Explicitly Disabled:** If the attribute is set to `false`, the alert points directly to the line of the incorrect configuration. - -## Detected Failure Cases - ---- - -### Case 1: Missing Configuration -* **Description:** The Backup Vault is defined without specifying the cross-region restore policy, leaving data vulnerable to regional failures. -* **Alert Location:** Resource level `azurerm_data_protection_backup_vault`. - -### Case 2: CRR Disabled -* **Description:** The `cross_region_restore_enabled` attribute is explicitly configured as `false`. -* **Alert Location:** Line `cross_region_restore_enabled`. - -## Involved Resource - -* `azurerm_data_protection_backup_vault` - -## Solution - -Set the `cross_region_restore_enabled` attribute to `true`. It is highly recommended to verify that the redundancy type (`redundancy`) is configured as `GeoRedundant`. - -```terraform -resource "azurerm_data_protection_backup_vault" "example_secure" { - name = "vault-secure" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - datastore_type = "VaultStore" - redundancy = "GeoRedundant" - - # Technical solution - cross_region_restore_enabled = true -} From 4d087483334320e244f6a384bbf0d6ac95473122 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:15:50 +0100 Subject: [PATCH 108/900] fix(queries): remove undocumented README.md from azure_backup_vault_infrastructure_encryption_disabled --- .../README.md | 42 ------------------- 1 file changed, 42 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/README.md deleted file mode 100644 index f1030a1f25a..00000000000 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# KICS Rule: Backup Vault Infrastructure Encryption Disabled - -## General Description - -This rule verifies readiness for advanced encryption in Azure backup vaults (**Data Protection Backup Vaults**). - -For a Backup Vault to support additional or customer-managed (CMK) encryption layers, the resource must have an assigned identity (`identity`). Without an identity, the vault can only use the platform's default encryption. - -## Rule Logic - -The policy audits the `azurerm_data_protection_backup_vault` resource: -1. Verifies the existence of the `identity` block. -2. If the block is absent, the resource is considered not ready for infrastructure or customer-managed encryption configurations. - -## Detected Failure Cases - -### Case 1: Identity Not Configured - -* **Description:** The Backup Vault does not have an identity (SystemAssigned or UserAssigned), which prevents linking to external encryption keys. -* **Alert Location:** Resource level `azurerm_data_protection_backup_vault`. - -## Involved Resource - -* `azurerm_data_protection_backup_vault` - -## Solution - -Add an `identity` block to the resource. - -```terraform -resource "azurerm_data_protection_backup_vault" "example" { - name = "vault-secure" - resource_group_name = "rg-example" - location = "West Europe" - datastore_type = "VaultStore" - redundancy = "LocallyRedundant" - - # Technical solution to enable encryption capabilities - identity { - type = "SystemAssigned" - } -} From a48820b4e66ede9b7af7e8e107c29042883406fa Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:15:52 +0100 Subject: [PATCH 109/900] fix(queries): remove undocumented README.md from azure_bastion_host_missing --- .../azure_bastion_host_missing/README.md | 50 ------------------- 1 file changed, 50 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_bastion_host_missing/README.md diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/README.md b/assets/queries/terraform/azure/azure_bastion_host_missing/README.md deleted file mode 100644 index 6b3a63a070f..00000000000 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# KICS Rule: Azure Bastion Host Missing - -## General Description - -This rule verifies that, if virtual networks (`azurerm_virtual_network`) are being deployed, at least one **Azure Bastion Host** resource (`azurerm_bastion_host`) is defined in the configuration. - -Azure Bastion is a PaaS service provisioned within a virtual network. It provides secure RDP and SSH connectivity directly from the Azure portal over SSL. This eliminates the need to expose administrative ports (22, 3389) to the Internet or manage complex VPNs and Jumpboxes for maintenance tasks, drastically reducing the attack surface. - -## Rule Logic - -The policy performs a resource presence analysis at the document level: -1. Checks whether any `azurerm_virtual_network` resource exists. -2. If networks exist, looks for any `azurerm_bastion_host` resource defined in the same file/context. -3. If networks exist but no Bastion Host is found, an alert is generated on the virtual network. - -## Detected Failure Cases - -### Case 1: VNet without Bastion Host - -* **Description:** Network infrastructure is defined, but the Bastion service is not included, suggesting that administrative access may be performed insecurely via direct public IPs or open ports in security groups (NSG). -* **Alert Location:** On the `azurerm_virtual_network` resource. - -## Involved Resource - -* `azurerm_virtual_network` -* `azurerm_bastion_host` - -## Solution - -To fix the issue, define an `azurerm_bastion_host` resource and make sure to create the mandatory subnet named `AzureBastionSubnet`. - -```terraform -resource "azurerm_subnet" "example_bastion" { - name = "AzureBastionSubnet" - resource_group_name = azurerm_resource_group.example.name - virtual_network_name = azurerm_virtual_network.example.name - address_prefixes = ["10.0.1.0/24"] -} - -resource "azurerm_bastion_host" "example" { - name = "production-bastion" - location = azurerm_resource_group.example.location - resource_group_name = azurerm_resource_group.example.name - - ip_configuration { - name = "configuration" - subnet_id = azurerm_subnet.example_bastion.id - public_ip_address_id = azurerm_public_ip.example.id - } -} From 013e072677ae35d6f5fe77f86ad79675a332c0e6 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:15:53 +0100 Subject: [PATCH 110/900] fix(queries): remove undocumented README.md from azure_defender_easm_enabled_manual --- .../README.md | 36 ------------------- 1 file changed, 36 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_defender_easm_enabled_manual/README.md diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/README.md b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/README.md deleted file mode 100644 index b724a63ae19..00000000000 --- a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# KICS Rule: Microsoft Defender EASM Enabled (Manual) - -## General Description - -This rule acts as a **manual compliance reminder**. Its objective is to ensure that **Microsoft Defender External Attack Surface Monitoring (EASM)** has been enabled to monitor the exposure of Azure assets to the Internet. - -EASM continuously discovers your digital assets (IP addresses, domains, SSL certificates, etc.) to identify vulnerabilities and risks in the "shadow" (Shadow IT). Since the current Terraform provider for Azure does not have native resources to manage this service, verification must be performed directly on the platform. - -## Rule Logic - -Due to the limitations of static analysis for this specific service: -1. The rule identifies the presence of `azurerm_resource_group` resources. -2. It generates an **INFO** severity alert for each detected group. -3. It acts as a checklist for the security team to validate the service status in the Azure Portal. - -## Detected Failure Cases - -### Case 1: Manual Verification Required - -* **Description:** Deployed infrastructure has been detected, but the EASM protection status is not visible to KICS. -* **Alert Location:** On the `azurerm_resource_group` resource. - -## Involved Resource - -* `azurerm_resource_group` - -## Solution - -This alert is not resolved through changes in standard HCL code. - -**Manual remediation steps:** -1. Access the [Azure Portal](https://portal.azure.com). -2. In the top search bar, type **"Microsoft Defender EASM"**. -3. Verify whether an EASM resource is configured and performing active scans. -4. If it does not exist, consider creating it to improve the external security posture. -5. Document the verification to close the finding in the KICS report. From 9638a4cf4e71e3d0a9fc1c64c6d17b52c42f1c73 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:15:54 +0100 Subject: [PATCH 111/900] fix(queries): remove undocumented README.md from azure_elastic_san_public_access_enabled --- .../README.md | 52 ------------------- 1 file changed, 52 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/README.md diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/README.md b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/README.md deleted file mode 100644 index 8eb70809996..00000000000 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# KICS Rule: Elastic SAN Public Network Access Enabled - -## General Description - -This KICS rule verifies that Azure Elastic SAN volume groups (`azurerm_elastic_san_volume_group`) have public network access restricted. - -In the Azure Elastic SAN architecture, network security and isolation are not managed at the root SAN resource level, but at the **Volume Group** level. To ensure that data volumes are not accessible from the Internet, it is essential to define the `network_rule` block. The mere presence of this block activates an implicit deny policy for any traffic that does not originate from authorized subnets, ensuring that the infrastructure is only accessible through the private network. - -## Rule Logic - -The policy audits the `azurerm_elastic_san_volume_group` resource by analyzing the following condition: -1. **Network Block Existence:** The presence of the `network_rule` block is verified. If this block is not defined, the volume group lacks perimeter restrictions, potentially allowing public access. - -## Detected Failure Case - -The following describes the scenario this policy will detect. - ---- - -### Single Case: Missing Network Configuration - -* **Description:** The volume group is defined without the `network_rule` block, meaning no IP filtering or virtual network rules are being applied to protect the data. -* **Example of Problematic Terraform Code:** - ```terraform - resource "azurerm_elastic_san_volume_group" "example_insecure" { - name = "insecure-vg" - elastic_san_id = azurerm_elastic_san.example.id - - # The resource lacks the network_rule block, - # leaving it exposed to public networks. - } - ``` -* **Alert Location:** On the root `azurerm_elastic_san_volume_group` resource. - -## Involved Resource - -* `azurerm_elastic_san_volume_group` - -## Solution - -To fix this security risk, define the `network_rule` block linking it to an authorized subnet via the `subnet_id` attribute. - -```terraform -resource "azurerm_elastic_san_volume_group" "secure_vg" { - name = "secure-volume-group" - elastic_san_id = azurerm_elastic_san.example.id - - # SOLUTION: Define network rules to deny public access - network_rule { - subnet_id = azurerm_subnet.example.id - } -} From faf3657352ee851a24d1c57d1534f3735eb72f88 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:15:55 +0100 Subject: [PATCH 112/900] fix(queries): remove undocumented README.md from azure_elastic_san_volume_group_cmk_encryption_disabled --- .../README.md | 68 ------------------- 1 file changed, 68 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/README.md deleted file mode 100644 index d26f9860843..00000000000 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# KICS Rule: Elastic SAN Volume Group CMK Encryption Disabled - -## General Description - -This KICS rule verifies that Azure Elastic SAN volume groups (`azurerm_elastic_san_volume_group`) are configured to use Customer-Managed Keys (CMK) for data encryption at rest. - -Using CMK over default platform-managed keys is a critical security practice. It provides organizations with full control over the lifecycle of cryptographic keys, including access policies, rotation, and revocation. This is essential for meeting regulatory requirements and ensuring that data stored in the SAN is protected by keys under the direct control of the customer. - -## Rule Logic - -The policy analyzes the `azurerm_elastic_san_volume_group` resource by validating two fundamental pillars: -1. **Type Configuration:** The `encryption_type` attribute must be unambiguously set to `EncryptionAtRestWithCustomerManagedKey`. -2. **Supporting Infrastructure:** If CMK is selected, the resource must mandatorily include both the `encryption` block (which links the key) and the `identity` block (which grants access to it). - -## Detected Failure Cases - -The following describes the scenarios this policy will detect. - ---- -### Case 1: CMK Encryption Not Configured (Platform Key Usage) - -* **Description:** The resource lacks the CMK encryption attribute or uses the default platform-managed value. -* **Example of Problematic Terraform Code:** - ```terraform - resource "azurerm_elastic_san_volume_group" "fail_platform" { - name = "example-vg" - elastic_san_id = azurerm_elastic_san.example.id - } - ``` -* **Alert Location:** Root `azurerm_elastic_san_volume_group` resource. - ---- -### Case 2: CMK Selected with Missing Technical Blocks - -* **Description:** The CMK encryption type has been activated, but one or both required blocks (`encryption` / `identity`) needed for the encryption to be operational are missing. -* **Example of Problematic Terraform Code:** - ```terraform - resource "azurerm_elastic_san_volume_group" "fail_missing_blocks" { - encryption_type = "EncryptionAtRestWithCustomerManagedKey" - # Missing encryption block or identity block - } - ``` -* **Alert Location:** Root `azurerm_elastic_san_volume_group` resource. - -## Involved Resource - -* `azurerm_elastic_san_volume_group` - -## Solution - -To fix the issue, make sure to declare the CMK encryption type and include the required technical blocks with their mandatory parameters. - -```terraform -resource "azurerm_elastic_san_volume_group" "secure_vg" { - name = "secure-volume-group" - elastic_san_id = azurerm_elastic_san.example.id - - encryption_type = "EncryptionAtRestWithCustomerManagedKey" - - encryption { - key_vault_key_id = azurerm_key_vault_key.example.id - } - - identity { - type = "UserAssigned" - identity_ids = [azurerm_user_assigned_identity.example.id] - } -} From f519067728c34044f14dacc701145ccea856be35 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:15:57 +0100 Subject: [PATCH 113/900] fix(queries): remove undocumented README.md from azure_iot_hub_defender_disabled --- .../azure_iot_hub_defender_disabled/README.md | 72 ------------------- 1 file changed, 72 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_iot_hub_defender_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/README.md b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/README.md deleted file mode 100644 index 5078491f285..00000000000 --- a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# KICS Rule: Azure IoT Hub Defender Disabled - -## General Description - -This KICS rule verifies that **Azure IoT Hub** resources (`azurerm_iothub`) are protected by **Microsoft Defender for IoT**. - -Microsoft Defender for IoT provides an essential layer of security for Internet of Things environments, offering real-time threat detection and security posture management. The lack of this protection leaves IoT devices and the Hub's central infrastructure vulnerable to targeted attacks, lateral movement, and data exfiltration. In Terraform, this protection is enabled by linking the IoT Hub with a resource of type `azurerm_iot_security_solution`. - -## Rule Logic - -The policy analyzes the Terraform configuration by performing the following steps: -1. **Hub Identification:** Selects all resources of type `azurerm_iothub`. -2. **Solution Verification:** Looks for `azurerm_iot_security_solution` resources in the document. -3. **Link Validation:** Checks whether the Hub's identifier is present in the `iothub_ids` list of any defined security solution, considering direct or interpolated formats. -4. **Alert Generation:** If a Hub is not referenced in any solution, a security finding is generated. - -## Detected Failure Case - -The following describes the scenario this policy will detect. - ---- - -### Single Case: IoT Hub without Associated Defender - -* **Description:** An `azurerm_iothub` resource is defined but no `azurerm_iot_security_solution` resource is found that includes it in its list of protected IDs. -* **Example of Problematic Terraform Code:** - ```terraform - resource "azurerm_iothub" "fail_hub" { - name = "insecure-iothub" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - - sku { - name = "S1" - capacity = "1" - } - } - - # No azurerm_iot_security_solution exists that references fail_hub - ``` -* **Alert Location:** On the root `azurerm_iothub` resource. - -## Involved Resource - -* `azurerm_iothub` -* `azurerm_iot_security_solution` - -## Solution - -To fix this risk, make sure to define an `azurerm_iot_security_solution` resource and include the IoT Hub ID in the `iothub_ids` attribute. - -```terraform -resource "azurerm_iothub" "example" { - name = "secure-iothub" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - - sku { - name = "S1" - capacity = "1" - } -} - -# SOLUTION: Define the security solution and link the Hub -resource "azurerm_iot_security_solution" "example" { - name = "iot-security-solution" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - display_name = "Iot Security Solution" - - iothub_ids = [azurerm_iothub.example.id] -} From da010e294a2dab939aec58f4c280f29be4d0f437 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:15:58 +0100 Subject: [PATCH 114/900] fix(queries): remove undocumented README.md from azure_key_vault_key_rotation_disabled --- .../README.md | 64 ------------------- 1 file changed, 64 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/README.md b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/README.md deleted file mode 100644 index 7cfdd5df575..00000000000 --- a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# KICS Rule: Key Vault Key Rotation Disabled - -## General Description - -This KICS rule verifies that cryptographic keys stored in Azure Key Vault (`azurerm_key_vault_key`) have an automatic rotation policy configured. - -Automatic key rotation is an essential security practice that limits the amount of data encrypted with a single key version and significantly reduces the impact if a key is compromised. Configuring a rotation policy ensures that keys are proactively renewed without manual intervention, guaranteeing operational continuity and compliance with security standards such as PCI-DSS or HIPAA. - -## Rule Logic - -The policy analyzes the `azurerm_key_vault_key` resource by performing the following steps: -1. **Key Identification:** Selects all resources of type `azurerm_key_vault_key`. -2. **Policy Verification:** Checks for the existence of the `rotation_policy` configuration block. -3. **Alert Generation:** If the block is absent, the key is considered to have no defined rotation strategy and a finding is generated. - -## Detected Failure Case - -The following describes the scenario this policy will detect. - ---- - -### Single Case: Key without Rotation Policy - -* **Description:** A cryptographic key is defined in Key Vault but the `rotation_policy` block is omitted, leaving the rotation responsibility to manual processes or allowing the key to remain indefinitely. -* **Example of Problematic Terraform Code:** - ```terraform - resource "azurerm_key_vault_key" "fail_key" { - name = "example-key" - key_vault_id = azurerm_key_vault.example.id - key_type = "RSA" - key_size = 2048 - key_opts = ["decrypt", "encrypt", "sign", "verify"] - - # The resource lacks the rotation_policy configuration - } - ``` -* **Alert Location:** On the root `azurerm_key_vault_key` resource. - -## Involved Resource - -* `azurerm_key_vault_key` - -## Solution - -To fix this risk, add the `rotation_policy` block defining the expiry time and the desired automatic rotation rules. - -```terraform -resource "azurerm_key_vault_key" "secure_key" { - name = "example-key" - key_vault_id = azurerm_key_vault.example.id - key_type = "RSA" - key_size = 2048 - key_opts = ["decrypt", "encrypt", "sign", "verify"] - - # SOLUTION: Define automatic rotation policy - rotation_policy { - expire_after = "P90D" - notify_before_expiry = "P29D" - - automatic { - time_before_expiry = "P30D" - } - } -} From 92c95cd0a30a9922221fd333282299eb8e0a6700 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:15:59 +0100 Subject: [PATCH 115/900] fix(queries): remove undocumented README.md from azure_managed_lustre_cmk_encryption_disabled --- .../README.md | 60 ------------------- 1 file changed, 60 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/README.md deleted file mode 100644 index a35e7ef8af0..00000000000 --- a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# KICS Rule: Azure Managed Lustre Not Encrypted with CMK - -## General Description - -This KICS rule verifies that **Azure Managed Lustre** file systems (`azurerm_managed_lustre_file_system`) are configured to use **Customer-Managed Keys (CMK)** for data encryption at rest. - -By default, Azure encrypts data in Lustre using platform-managed keys. To meet data sovereignty and governance requirements, the use of CMK via the `encryption_key` block is recommended. This gives organizations full control over the key lifecycle, allowing rotation and selective revocation of access to the high-performance data stored in the file system. - -## Rule Logic - -The policy analyzes the `azurerm_managed_lustre_file_system` resource by validating the following condition: -1. **Encryption Block Presence:** The existence of the `encryption_key` block is verified. If this block is not defined, the file system defaults to Azure-managed encryption. - -## Detected Failure Case - -The following describes the scenario this policy will detect. - ---- - -### Single Case: Use of Platform-Managed Keys (Block Absent) - -* **Description:** The Lustre file system is defined without the customer encryption configuration block, delegating data protection to the platform's default keys. -* **Example of Problematic Terraform Code:** - ```terraform - resource "azurerm_managed_lustre_file_system" "example_insecure" { - name = "insecure-lustre" - resource_group_name = "rg-example" - location = "West Europe" - sku_name = "AMLFS-Durable-Premium-250" - subnet_id = azurerm_subnet.example.id - storage_capacity_in_tb = 48 - - # The resource lacks the encryption_key block - } - ``` -* **Alert Location:** On the root `azurerm_managed_lustre_file_system` resource. - -## Involved Resource - -* `azurerm_managed_lustre_file_system` - -## Solution - -To fix this risk, define the `encryption_key` block providing the key URL and the source Key Vault ID. - -```terraform -resource "azurerm_managed_lustre_file_system" "secure_lustre" { - name = "secure-lustre" - resource_group_name = "rg-example" - location = "West Europe" - sku_name = "AMLFS-Durable-Premium-250" - subnet_id = azurerm_subnet.example.id - storage_capacity_in_tb = 48 - - # SOLUTION: Configure encryption with CMK - encryption_key { - key_url = azurerm_key_vault_key.example.id - source_vault_id = azurerm_key_vault.example.id - } -} From 1713f64da28e1ca0e05d5e62dfe4b4a72f6c8090 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:00 +0100 Subject: [PATCH 116/900] fix(queries): remove undocumented README.md from azure_mysql_audit_log_enabled_manual --- .../README.md | 59 ------------------- 1 file changed, 59 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/README.md diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/README.md b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/README.md deleted file mode 100644 index d387e7ae51d..00000000000 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# KICS Rule: MySQL Audit Log Enabled (Manual) - -## General Description - -This KICS rule acts as a manual control to ensure that the server parameter `audit_log_enabled` is set to `ON` in **Azure Database for MySQL** instances. - -Audit logs are essential for database observability and security. They allow tracking of specific events, such as connection attempts, DDL query execution, and user privilege changes. Because in Azure MySQL these parameters can be managed externally to the server resource (either through the portal or via independent configuration resources), manual validation is required to confirm compliance. - -## Rule Logic - -Since the audit configuration does not necessarily reside within the main MySQL server block in Terraform, the static analysis focuses on: -1. **Resource Identification:** The rule locates all resources of type `azurerm_mssql_server` and `azurerm_mysql_flexible_server`. -2. **Audit Reminder:** Generates an informational severity finding to alert the administrator of the need to verify the status of the `audit_log_enabled` parameter. - -## Detected Failure Case - -The following describes the scenario this policy will detect. - ---- - -### Single Case: Manual Verification Required - -* **Description:** The presence of a MySQL server is detected. Since the audit status is not always statically verifiable from the server resource, a manual review is requested. -* **Example of Problematic Terraform Code:** - ```terraform - resource "azurerm_mssql_server" "example_insecure" { - name = "mysql-server-audit-check" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - # The status of audit_log_enabled is not visible here. - } - ``` -* **Alert Location:** On the detected MySQL server resource. - -## Involved Resource - -* `azurerm_mssql_server` -* `azurerm_mysql_flexible_server` - -## Solution - -There are two methods to ensure that auditing is enabled: - -### Option A: Manual Verification (Azure Portal) -1. Navigate to your MySQL server in the Azure Portal. -2. Go to the **Server parameters** section. -3. Search for the `audit_log_enabled` parameter and confirm its value is `ON`. - -### Option B: Configuration as Code (Recommended) -Use the `azurerm_mysql_configuration` resource (for Single Server) or `azurerm_mysql_flexible_server_configuration` (for Flexible Server) to enforce the parameter: - -```terraform -# Example for MySQL Single Server -resource "azurerm_mysql_configuration" "audit_log" { - name = "audit_log_enabled" - resource_group_name = azurerm_resource_group.example.name - server_name = azurerm_mssql_server.example.name - value = "ON" -} From 70add5f9d759614d61e84f80215c86d120a23a2e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:02 +0100 Subject: [PATCH 117/900] fix(queries): remove undocumented README.md from azure_mysql_audit_log_events_connection_manual --- .../README.md | 59 ------------------- 1 file changed, 59 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/README.md diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/README.md b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/README.md deleted file mode 100644 index 4b55e834e7f..00000000000 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# KICS Rule: MySQL Audit Log Events Connection (Manual) - -## General Description - -This KICS rule acts as a manual control to verify that the server parameter `audit_log_events` includes the value `CONNECTION` in **Azure Database for MySQL** servers. - -Logging `CONNECTION` type events is a fundamental piece of the security and compliance strategy. It allows administrators and auditors to track who accesses the database, detect brute force attacks (failed attempts), and audit suspicious sessions. Without this configuration, visibility into initial access to data resources is lost, making incident response more difficult. - -## Rule Logic - -Because static analysis cannot always guarantee verification of a text string within an independent configuration resource (`azurerm_mysql_configuration`), this rule applies a preventive approach: -1. **Resource Identification:** Detects all instances of `azurerm_mssql_server` and `azurerm_mysql_flexible_server`. -2. **Security Reminder:** Generates an informational alert for the auditor to specifically verify that connection events are being captured. - -## Detected Failure Case - -The following describes the scenario this policy will detect. - ---- - -### Single Case: Manual Verification Required - -* **Description:** A provisioned MySQL server is detected. KICS issues an alert to ensure that the audited event types include connections, since this configuration may be delegated to other resources or the portal. -* **Example of Problematic Terraform Code:** - ```terraform - resource "azurerm_mssql_server" "example_audit_check" { - name = "mysql-server-connection-check" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - # The content of audit_log_events is not verifiable here. - } - ``` -* **Alert Location:** On the detected MySQL server resource. - -## Involved Resource - -* `azurerm_mssql_server` -* `azurerm_mysql_flexible_server` - -## Solution - -### Option A: Manual Verification (Azure Portal) -1. Navigate to the MySQL server in the Azure Portal. -2. Go to the **Server parameters** section. -3. Locate the `audit_log_events` parameter. -4. Ensure that `CONNECTION` is included among the selected values. - -### Option B: Configuration via Terraform -Make sure to explicitly include the value in the configuration resource: - -```terraform -resource "azurerm_mysql_configuration" "audit_events" { - name = "audit_log_events" - resource_group_name = azurerm_resource_group.example.name - server_name = azurerm_mssql_server.example.name - - # SOLUTION: Include CONNECTION in the list of events - value = "CONNECTION,QUERY,DDL" -} From 58c1ffab03fe5802743e126afed26f1cf49d234d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:03 +0100 Subject: [PATCH 118/900] fix(queries): remove undocumented README.md from azure_netapp_account_cmk_encryption_disabled --- .../README.md | 65 ------------------- 1 file changed, 65 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/README.md deleted file mode 100644 index d644eaa261e..00000000000 --- a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# KICS Rule: NetApp Account CMK Encryption Disabled - -## General Description - -This KICS rule verifies that **Azure NetApp Files** accounts are configured to use **Customer-Managed Keys (CMK)** for data encryption at rest. - -By default, Azure NetApp Files encrypts data using Microsoft platform-managed keys. However, to meet regulatory compliance and data sovereignty requirements, the use of CMK is recommended. This allows organizations to have full control over the key lifecycle, including rotation and access revocation, ensuring that high-performance storage volumes are protected by keys under the direct control of the customer in Azure Key Vault. - -## Rule Logic - -The policy analyzes the Terraform configuration looking for two valid CMK implementation methods: -1. **Inline Configuration:** Checks whether the `azurerm_netapp_account` resource has an `encryption` block where the `key_source` attribute is explicitly `Microsoft.KeyVault`. -2. **Standalone Resource:** Checks whether an `azurerm_netapp_account_encryption` resource exists linked to the analyzed NetApp account's ID. - -If neither of these two methods is detected, an alert is generated indicating that the account is operating with the platform's default encryption. - -## Detected Failure Case - -The following describes the scenario this policy will detect. - ---- - -### Single Case: Default Encryption Configuration (Platform Keys) - -* **Description:** The NetApp account is defined without enabling Key Vault for encryption, leaving the data protected only by Microsoft keys. -* **Example of Problematic Terraform Code:** - ```terraform - resource "azurerm_netapp_account" "fail" { - name = "insecure-netapp-account" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - - # Missing CMK configuration (inline or separate resource) - } - ``` -* **Alert Location:** On the root `azurerm_netapp_account` resource. - -## Involved Resources - -* `azurerm_netapp_account` -* `azurerm_netapp_account_encryption` - -## Solution - -To fix this risk, assign a managed identity to the account and use the `azurerm_netapp_account_encryption` resource to link the Key Vault key. - -```terraform -resource "azurerm_netapp_account" "secure" { - name = "secure-netapp-account" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - - # 1. Assign identity - identity { - type = "UserAssigned" - identity_ids = [azurerm_user_assigned_identity.example.id] - } -} - -# 2. Configure CMK encryption via the dedicated resource -resource "azurerm_netapp_account_encryption" "secure_encryption" { - netapp_account_id = azurerm_netapp_account.secure.id - user_assigned_identity_id = azurerm_user_assigned_identity.example.id - encryption_key = azurerm_key_vault_key.example.versionless_id -} From 104f26e819e051700c3f72ed80044b38f786bec8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:04 +0100 Subject: [PATCH 119/900] fix(queries): remove undocumented README.md from azure_paas_private_endpoint_missing --- .../README.md | 67 ------------------- 1 file changed, 67 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_paas_private_endpoint_missing/README.md diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/README.md b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/README.md deleted file mode 100644 index 64aae415fac..00000000000 --- a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# KICS Rule: Azure PaaS Services Private Endpoint Disabled (Master) - -## General Description - -This is a consolidated rule (**Master Rule**) designed to ensure that critical Azure PaaS services are protected through the use of **Private Endpoints**. - -Private Endpoints are an essential component of perimeter security in Azure. They allow services (such as databases, storage, or key vaults) to integrate directly into a Virtual Network (VNet). By assigning a private IP address from the VNet's address space to the service, the need to expose those resources to the public internet is eliminated, drastically reducing the attack surface and preventing data exfiltration. - -## Rule Logic - -The policy comprehensively analyzes resources defined in Terraform looking for a valid link: -1. **Target Resources:** The rule monitors an extensive list of services, including `azurerm_storage_account`, `azurerm_mssql_server`, `azurerm_cosmosdb_account`, `azurerm_key_vault`, and other data and messaging services. -2. **Link Validation:** For each detected resource, it looks for the existence of an `azurerm_private_endpoint` resource that references it through the `private_connection_resource_id` attribute. -3. **Result:** If the PaaS resource exists but there is no associated private endpoint in the same code context, an alert is generated. - -## Static Analysis Limitations - -It is important to note that this rule validates the configuration **within the same Terraform file or state**. Due to the nature of static analysis: -* It cannot validate connections if the resource is created in a different subscription or managed in a separate Terraform state. -* It may generate false positives if the endpoint is defined through external modules whose variables are not resolved by the scanning engine. - -## Detected Failure Case - -The following describes the main scenario this policy will detect. - ---- - -### Single Case: Isolated PaaS Resource (No Private Endpoint) - -* **Description:** A critical service (e.g., Azure SQL or Storage Account) has been defined but the private endpoint that ensures traffic is internal to the VNet has not been provisioned. -* **Example of Problematic Terraform Code:** - ```terraform - resource "azurerm_storage_account" "example_insecure" { - name = "stinsecuredata" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "LRS" - - # The resource exists but lacks a linked azurerm_private_endpoint - } - ``` -* **Alert Location:** On the identified PaaS resource (Storage, SQL, Key Vault, etc.). - -## Involved Resources - -* `azurerm_private_endpoint` -* PaaS Services (Storage, SQL, Cosmos, KeyVault, ACR, ServiceBus, etc.) - -## Solution - -To fix this finding, you must create an `azurerm_private_endpoint` resource and link it to the PaaS resource ID via the `private_service_connection` block. - -```terraform -resource "azurerm_private_endpoint" "example_secure" { - name = "pe-storage" - location = azurerm_resource_group.example.location - resource_group_name = azurerm_resource_group.example.name - subnet_id = azurerm_subnet.example.id - - private_service_connection { - name = "psc-storage" - private_connection_resource_id = azurerm_storage_account.example_insecure.id - is_manual_connection = false - subresource_names = ["blob"] - } -} From d31df5de1b35e01a8ff2559db372dc38a0bac5f7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:06 +0100 Subject: [PATCH 120/900] fix(queries): remove undocumented README.md from azure_production_workload_basic_consumption_sku --- .../README.md | 69 ------------------- 1 file changed, 69 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/README.md diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/README.md b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/README.md deleted file mode 100644 index 3aca3e0d337..00000000000 --- a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# KICS Rule: Production Workload using Basic or Consumption SKU - -## General Description - -This rule identifies Azure resources configured with **Basic**, **Free**, or **Consumption** pricing tiers (SKUs). - -Although these tiers are ideal for development, learning, or proof-of-concept (PoC) environments, they lack fundamental features required for production environments. Using these SKUs in production compromises service reliability due to the absence of guaranteed Service Level Agreements (SLAs), lack of support for virtual network (VNet) integration, absence of deployment slots, and unexpected latencies ("cold starts") in serverless consumption models. - -## Rule Logic - -The policy audits the following resources in the Terraform configuration: -1. **Service Plans (`azurerm_service_plan`):** Alerts if the `sku_name` attribute is set to non-production tiers such as B1-B3, F1, FREE, or Y1. -2. **API Management (`azurerm_api_management`):** Alerts if the `sku_name` attribute matches patterns of type "Basic" or "Consumption". - -## Detected Failure Cases - -The following describes the scenarios this policy will detect. - ---- - -### Case 1: Service Plan at Non-Production Tier - -* **Description:** An App Service plan is detected configured at Basic or Free tier, which limits the availability and network capabilities of the service. -* **Example of Problematic Terraform Code:** - ```terraform - resource "azurerm_service_plan" "fail_plan" { - name = "example-basic-plan" - resource_group_name = "rg-production" - location = "West Europe" - os_type = "Linux" - sku_name = "B1" # <-- FAILURE: Basic Tier - } - ``` -* **Alert Location:** `sku_name` attribute. - ---- - -### Case 2: API Management in Consumption Mode - -* **Description:** An APIM instance is detected at the Consumption (Serverless) tier, which may affect performance and lacks network isolation. -* **Example of Problematic Terraform Code:** - ```terraform - resource "azurerm_api_management" "fail_apim" { - name = "example-apim" - sku_name = "Consumption_0" # <-- FAILURE: Consumption Tier - # ... rest of configuration ... - } - ``` -* **Alert Location:** `sku_name` attribute. - -## Involved Resource - -* `azurerm_service_plan` -* `azurerm_api_management` - -## Solution - -Update the resource SKU to a production-oriented tier, such as **Standard (S)** or **Premium (P)**, to guarantee the SLA and the necessary network features. - -```terraform -resource "azurerm_service_plan" "secure_production" { - name = "prod-service-plan" - resource_group_name = "rg-production" - location = "West Europe" - os_type = "Linux" - - # SOLUTION: Use a Standard tier or higher - sku_name = "S1" -} From 43327e2c9100945874ffef81c77cd3424e456c3f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:07 +0100 Subject: [PATCH 121/900] fix(queries): remove undocumented README.md from azure_recovery_services_vault_cmk_encryption_disabled --- .../README.md | 61 ------------------- 1 file changed, 61 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/README.md deleted file mode 100644 index f43c35658bc..00000000000 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# KICS Rule: Recovery Services Vault CMK Encryption Disabled - -## General Description - -This KICS rule verifies that **Recovery Services Vault** vaults (used for Azure Backup and Azure Site Recovery) are configured to use **Customer-Managed Keys (CMK)** for data encryption at rest. - -By default, backed-up data is encrypted using Microsoft platform-managed keys. However, to comply with regulatory requirements and ensure data sovereignty, organizations must use their own keys stored in Azure Key Vault. This allows full control over key rotation, access policies, and the ability to revoke access to backup data when needed. - -## Rule Logic - -The policy analyzes the `azurerm_recovery_services_vault` resource by validating the following technical condition: -1. **Presence of the Encryption Block:** The existence of the `encryption` block is checked. The absence of this block implies that the vault uses the default platform-managed encryption, which does not meet CMK requirements. - -## Detected Failure Case - -The following describes the scenario that this policy will detect. - ---- - -### Single Case: Use of Platform Keys (Default Encryption) - -* **Description:** The Recovery Services Vault is defined without the customer encryption configuration block, delegating data protection to Azure's automatic keys. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_recovery_services_vault" "fail_vault" { - name = "insecure-vault" - location = "West Europe" - resource_group_name = "rg-production" - sku = "Standard" - - # The resource lacks the encryption {} block - } - ``` -* **Alert Location:** On the root `azurerm_recovery_services_vault` resource. - -## Involved Resource - -* `azurerm_recovery_services_vault` - -## Solution - -To resolve this finding, you must enable a managed identity on the Vault and configure the `encryption` block by mandatorily providing the `key_id` from Azure Key Vault. - -```terraform -resource "azurerm_recovery_services_vault" "secure_vault" { - name = "secure-recovery-vault" - location = azurerm_resource_group.example.location - resource_group_name = azurerm_resource_group.example.name - sku = "Standard" - - # 1. Enable identity for Key Vault access - identity { - type = "SystemAssigned" - } - - # 2. Configure CMK encryption (key_id is required in this block) - encryption { - key_id = azurerm_key_vault_key.example.id - use_system_assigned_identity = true - } -} From d4aa64964e69bebbcc16911a35278461694a1916 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:08 +0100 Subject: [PATCH 122/900] fix(queries): remove undocumented README.md from azure_recovery_services_vault_cross_region_restore_disabled --- .../README.md | 72 ------------------- 1 file changed, 72 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/README.md b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/README.md deleted file mode 100644 index bf17023f60d..00000000000 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# KICS Rule: Recovery Services Vault Cross Region Restore Disabled - -## General Description - -This KICS rule verifies that the **Cross Region Restore** functionality (`cross_region_restore_enabled`) is enabled in **Recovery Services Vault** vaults. - -Enabling Cross Region Restore (CRR) is a critical component of a business continuity and disaster recovery strategy (DRP). This feature allows data restores to be performed in a secondary paired Azure region at any time, ensuring access to backups even if the primary region suffers a total outage or regional disaster. - -**Technical note:** For cross-region restore to be effective, the vault must have its storage type configured as `GeoRedundant`. - -## Rule Logic - -The policy analyzes the `azurerm_recovery_services_vault` resource by evaluating two conditions: -1. **Missing Attribute:** If `cross_region_restore_enabled` is not explicitly defined, it is considered non-compliant, since the default configuration does not guarantee data availability in the secondary region. -2. **Incorrect Configuration:** If the attribute is explicitly set to `false`, an alert is generated indicating the lack of operational redundancy for restores. - -## Detected Failure Cases - -The following describes the scenarios that this policy will detect. - ---- - -### Case 1: Missing CRR Configuration - -* **Description:** The vault is defined without specifying the regional restore policy, resulting in the default deactivation of this resilience measure. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_recovery_services_vault" "fail_missing" { - name = "vault-insecure" - location = "West Europe" - resource_group_name = azurerm_resource_group.example.name - sku = "Standard" - storage_mode_type = "GeoRedundant" - # Missing cross_region_restore_enabled = true - } - ``` -* **Alert Location:** On the root `azurerm_recovery_services_vault` resource. - ---- - -### Case 2: CRR Explicitly Disabled - -* **Description:** The `cross_region_restore_enabled` attribute has been configured with the value `false`, preventing disaster recovery in paired regions. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_recovery_services_vault" "fail_false" { - name = "vault-disabled" - storage_mode_type = "GeoRedundant" - cross_region_restore_enabled = false # <-- Detected issue - } - ``` -* **Alert Location:** `cross_region_restore_enabled` attribute. - -## Involved Resource - -* `azurerm_recovery_services_vault` - -## Solution - -Set `cross_region_restore_enabled` to `true` and ensure that `storage_mode_type` is `GeoRedundant`. - -```terraform -resource "azurerm_recovery_services_vault" "secure_vault" { - name = "vault-resilient" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - sku = "Standard" - storage_mode_type = "GeoRedundant" - - # SOLUTION: Enable cross-region restore - cross_region_restore_enabled = true -} From 179a04a0bce653b6103eb353bf49f435d234dd05 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:09 +0100 Subject: [PATCH 123/900] fix(queries): remove undocumented README.md from azure_recovery_services_vault_infrastructure_encryption_disabled --- .../README.md | 79 ------------------- 1 file changed, 79 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/README.md deleted file mode 100644 index 1958a059a80..00000000000 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# KICS Rule: Recovery Services Vault Infrastructure Encryption Disabled - -## General Description - -This KICS rule verifies that **Infrastructure Encryption** (`infrastructure_encryption_enabled`) is enabled in **Recovery Services Vault** vaults. - -Infrastructure encryption provides an additional layer of protection through the use of a second encryption algorithm (**Double Encryption**). While all data in Azure is already encrypted at rest, enabling this option ensures that data is encrypted twice using two independent algorithms. This configuration is essential for organizations with highly strict compliance requirements seeking to mitigate risks against potential vulnerabilities in a single cryptographic standard. - -## Rule Logic - -The policy analyzes the `azurerm_recovery_services_vault` resource by validating two technical aspects: -1. **Encryption Block:** Verifies the existence of the `encryption` block. If it does not exist, it is assumed that there is no double encryption. -2. **Infrastructure Encryption:** Verifies that the `infrastructure_encryption_enabled` attribute is explicitly set to `true`. - -## Detected Failure Cases - -The following describes the scenarios that this policy will detect. - ---- - -### Case 1: Missing Encryption Block - -* **Description:** The vault does not have the `encryption` block defined, so it uses only Azure's default encryption without additional layers. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_recovery_services_vault" "fail_missing" { - name = "insecure-vault" - resource_group_name = "rg-prod" - location = "West Europe" - sku = "Standard" - # Missing encryption {} block - } - ``` -* **Alert Location:** On the root `azurerm_recovery_services_vault` resource. - ---- - -### Case 2: Infrastructure Encryption Disabled - -* **Description:** The `encryption` block exists but the `infrastructure_encryption_enabled` attribute is not configured or is set to `false`. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_recovery_services_vault" "fail_disabled" { - name = "vault-vulnerable" - # ... - encryption { - key_id = azurerm_key_vault_key.example.id - infrastructure_encryption_enabled = false - use_system_assigned_identity = true - } - } - ``` -* **Alert Location:** `infrastructure_encryption_enabled` attribute. - -## Involved Resource - -* `azurerm_recovery_services_vault` - -## Solution - -To mitigate this risk, ensure you declare the `encryption` block setting `infrastructure_encryption_enabled` to `true`. - -```terraform -resource "azurerm_recovery_services_vault" "secure_vault" { - name = "secure-recovery-vault" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - sku = "Standard" - - identity { - type = "SystemAssigned" - } - - encryption { - key_id = azurerm_key_vault_key.example.id - infrastructure_encryption_enabled = true - use_system_assigned_identity = true - } -} From ff7b1703e768c23d0d7d19087b7eec7b637cc210 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:11 +0100 Subject: [PATCH 124/900] fix(queries): remove undocumented README.md from azure_sql_server_tde_cmk_disabled --- .../README.md | 56 ------------------- 1 file changed, 56 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/README.md b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/README.md deleted file mode 100644 index ee4292a68dd..00000000000 --- a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# KICS Rule: SQL Server TDE Not Encrypted with CMK - -## General Description - -This KICS rule ensures that the **Transparent Data Encryption (TDE)** feature of Azure SQL Server is configured to use a **Customer-Managed Key (CMK)** stored in Azure Key Vault. - -By default, Azure SQL encrypts data at rest using a service-managed key (Microsoft). Although this method provides baseline security, using CMK offers a superior level of control that is indispensable for meeting strict corporate security regulations. With CMK, the organization assumes full control over the key lifecycle, allowing rotation, access revocation, and usage auditing in a sovereign manner through Azure Key Vault. - -## Rule Logic - -The policy audits the Terraform configuration following these criteria: -1. **Identification:** Locates all resources of type `azurerm_mssql_server`. -2. **Linking:** Checks whether an independent resource of type `azurerm_mssql_server_transparent_data_encryption` exists linked to the server via the `server_id` attribute. -3. **Key Validation:** Verifies that said resource has the `key_vault_key_id` attribute explicitly defined. -4. **Alert:** If the encryption resource is not found or if the Key Vault key reference is missing, a finding is generated. - -## Detected Failure Case - -The following describes the scenario this policy will detect. - ---- - -### Single Case: Use of Service-Managed Key (Default) - -* **Description:** The SQL server is defined but the additional resource required to enable TDE encryption using customer keys is not added, maintaining Azure's default encryption. -* **Example of Problematic Terraform Code:** - ```terraform - resource "azurerm_mssql_server" "fail_server" { - name = "insecure-sql-server" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - version = "12.0" - administrator_login = "sqladmin" - administrator_password = "P@ssword123!" - - # Missing azurerm_mssql_server_transparent_data_encryption resource - } - ``` -* **Alert Location:** On the root `azurerm_mssql_server` resource. - -## Involved Resources - -* `azurerm_mssql_server` -* `azurerm_mssql_server_transparent_data_encryption` - -## Solution - -To mitigate this risk, create an `azurerm_mssql_server_transparent_data_encryption` resource, link it to the SQL server, and provide the Azure Key Vault key URI. - -```terraform -resource "azurerm_mssql_server_transparent_data_encryption" "secure_tde" { - server_id = azurerm_mssql_server.example.id - - # SOLUTION: Use a customer-managed key - key_vault_key_id = azurerm_key_vault_key.example.id -} From fd64c285640f352f342799c1d539fab5bb3b6313 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:12 +0100 Subject: [PATCH 125/900] fix(queries): remove undocumented README.md from azure_storage_account_geo_redundancy_disabled --- .../README.md | 55 ------------------- 1 file changed, 55 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/README.md b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/README.md deleted file mode 100644 index 67b9e724aa9..00000000000 --- a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# KICS Rule: Storage Account Geo-Redundancy Disabled - -## General Description - -This KICS rule verifies that Azure storage accounts (`azurerm_storage_account`) are configured with **Geo-Redundancy**. - -Geo-redundancy is a fundamental business continuity strategy. By enabling it, Azure asynchronously copies data to a secondary region located hundreds of kilometers from the primary region. This ensures that, in the event of a catastrophic regional disaster (massive network failures, natural disasters, or region-wide power outages), data remains durable and available for recovery, minimizing RPO (Recovery Point Objective) and RTO (Recovery Time Objective). - -## Rule Logic - -The policy audits the `account_replication_type` attribute of the `azurerm_storage_account` resource: -1. **Type Validation:** Checks whether the configured value belongs to the high regional availability group: `GRS`, `RAGRS`, `GZRS`, or `RAGZRS`. -2. **Risk Detection:** If the value is `LRS` (Locally Redundant) or `ZRS` (Zone Redundant), an alert is generated, as these levels only protect against hardware failures within a datacenter or zone, but not against the loss of an entire region. - -## Detected Failure Case - -The following describes the scenario that this policy will detect. - ---- - -### Single Case: Local or Zonal Replication (LRS/ZRS) - -* **Description:** The storage account uses a replication scheme that does not extend beyond the primary region, leaving data vulnerable to regional disasters. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_storage_account" "fail_storage" { - name = "insecurestorage" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - - # FAILURE: Replication limited to the local region - account_replication_type = "LRS" - } - ``` -* **Alert Location:** `account_replication_type` attribute. - -## Involved Resource - -* `azurerm_storage_account` - -## Solution - -To mitigate this risk in production environments, change the replication type to one that supports geo-redundancy, such as **GRS**. - -```terraform -resource "azurerm_storage_account" "secure_storage" { - name = "securestorage" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - - # SOLUTION: Enable geo-redundancy - account_replication_type = "GRS" -} From 20603a5f98d8e7e6449aa87d87c7801811d8c81d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:13 +0100 Subject: [PATCH 126/900] fix(queries): remove undocumented README.md from azure_storage_account_infrastructure_encryption_disabled --- .../README.md | 72 ------------------- 1 file changed, 72 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/README.md b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/README.md deleted file mode 100644 index d4240c2310f..00000000000 --- a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# KICS Rule: Storage Account Infrastructure Encryption Disabled - -## General Description - -This KICS rule verifies that **Infrastructure Encryption** (`infrastructure_encryption_enabled`) is enabled on `azurerm_storage_account` resources. - -By default, Azure Storage encrypts all data at rest using server-side encryption (SSE) with Microsoft-managed keys. However, enabling infrastructure encryption provides a defense-in-depth layer known as **Double Encryption**. In this model, data is encrypted twice: once at the storage service level and once at the underlying infrastructure level, using two independent encryption algorithms and distinct keys. This protects information even in the unlikely event that a single algorithm or key is compromised. - -**Technical note:** This setting is **immutable**. It can only be enabled at the time of storage account creation; it cannot be activated afterwards without recreating the resource. - -## Rule Logic - -The policy audits the `azurerm_storage_account` resource by evaluating two scenarios: -1. **Missing Attribute:** If `infrastructure_encryption_enabled` is not explicitly defined, KICS assumes the default value (`false`) and generates an alert on the resource. -2. **Explicitly Disabled:** If the attribute is configured as `false`, an alert is generated indicating that double encryption protection is not active. - -## Detected Failure Cases - -The following describes the scenarios that this policy will detect. - ---- - -### Case 1: Missing Double Encryption Configuration - -* **Description:** The storage account is defined without including the infrastructure encryption parameter, delegating security solely to the default single encryption. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_storage_account" "fail_missing" { - name = "storageinsecure" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "LRS" - # Missing infrastructure_encryption_enabled = true - } - ``` -* **Alert Location:** On the root `azurerm_storage_account` resource. - ---- - -### Case 2: Infrastructure Encryption Explicitly Disabled - -* **Description:** The `infrastructure_encryption_enabled` attribute has been configured as `false`, disabling the required additional security layer. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_storage_account" "fail_explicit" { - name = "storagedisabled" - # ... - infrastructure_encryption_enabled = false # <-- Detected issue - } - ``` -* **Alert Location:** `infrastructure_encryption_enabled` attribute. - -## Involved Resource - -* `azurerm_storage_account` - -## Solution - -To mitigate this risk, set `infrastructure_encryption_enabled` to `true` during the initial definition of the storage account. - -```terraform -resource "azurerm_storage_account" "secure_storage" { - name = "storage-secure" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "GRS" - - # SOLUTION: Enable infrastructure double encryption - infrastructure_encryption_enabled = true -} From ea4e0aff29ebb05d4f6eabd9126edd07333ca226 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:14 +0100 Subject: [PATCH 127/900] fix(queries): remove undocumented README.md from azure_storage_account_read_only_lock_missing --- .../README.md | 63 ------------------- 1 file changed, 63 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/README.md diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/README.md b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/README.md deleted file mode 100644 index ccc9dec05ce..00000000000 --- a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# KICS Rule: Storage Account ReadOnly Lock Missing - -## General Description - -This KICS rule verifies that Azure storage accounts (`azurerm_storage_account`) have a **resource lock** (`azurerm_management_lock`) applied, specifically configured at the **`ReadOnly`** level. - -Azure Resource Manager (ARM) locks provide an additional security layer that transcends RBAC permissions. Applying a `ReadOnly` type lock to a storage account ensures that the resource configuration (such as firewall rules, access tiers, or replication settings) cannot be modified or the resource accidentally deleted, even by administrators. It is an essential practice for critical data assets in production environments. - -## Rule Logic - -The policy performs a cross-analysis between storage account resources and defined locks: -1. **Identification:** Locates all instances of `azurerm_storage_account`. -2. **Linking:** Searches for `azurerm_management_lock` resources whose `scope` attribute references the Storage Account ID. -3. **Level Validation:** Verifies that the `lock_level` attribute is strictly `"ReadOnly"`. -4. **Finding Generation:** If the resource has no lock, or if existing locks have a lower level (such as `CanNotDelete`), an alert is generated. - -## Detected Failure Cases - -### Case 1: Storage Account Without a Lock - -* **Description:** The storage account has been deployed without any management restriction, allowing accidental modifications. -* **Alert Location:** On the root `azurerm_storage_account` resource. - ---- - -### Case 2: Lock With Incorrect Level - -* **Description:** A lock associated with the resource exists, but its level is `"CanNotDelete"`, which allows modifications to the configuration that this rule seeks to restrict via `"ReadOnly"`. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_management_lock" "fail_lock" { - name = "prevent-deletion" - scope = azurerm_storage_account.example.id - lock_level = "CanNotDelete" # <-- FAILURE: 'ReadOnly' is required - } - ``` -* **Alert Location:** `lock_level` attribute of the lock resource. - -## Involved Resources - -* `azurerm_storage_account` -* `azurerm_management_lock` - -## Solution - -Add an `azurerm_management_lock` resource pointing to the storage account ID with the `ReadOnly` level. - -```terraform -resource "azurerm_storage_account" "secure_sa" { - name = "storage-prod-critical" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "GRS" -} - -# SOLUTION: Apply ReadOnly lock -resource "azurerm_management_lock" "sa_readonly_lock" { - name = "critical-storage-lock" - scope = azurerm_storage_account.secure_sa.id - lock_level = "ReadOnly" - notes = "Security lock for governance policy compliance" -} From 3106090f4872e92975c6764d7c42b2b70e1a111e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:16 +0100 Subject: [PATCH 128/900] fix(queries): remove undocumented README.md from azure_storage_account_versioning_disabled --- .../README.md | 76 ------------------- 1 file changed, 76 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_account_versioning_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/README.md b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/README.md deleted file mode 100644 index d786deae52f..00000000000 --- a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# KICS Rule: Storage Account Blob Versioning Disabled - -## General Description - -This rule verifies that the **Versioning** feature (version control) is enabled on `azurerm_storage_account` resources. - -Blob versioning allows automatically maintaining previous versions of an object when it is modified or deleted. It is a fundamental protection layer for data recovery scenarios involving human errors, accidental overwrites, or ransomware attacks, allowing restoration of a previous state of the file without needing to resort to complex external backups. - -## Rule Logic - -The policy evaluates the configuration at three levels of granularity: -1. **Missing Block:** If the resource does not have the `blob_properties` block defined. -2. **Missing Attribute:** If the block exists but the `versioning_enabled` parameter is not defined. -3. **Incorrect Value:** If `versioning_enabled` has been explicitly configured as `false`. - -## Detected Failure Cases - -The following describes the scenarios that this policy will detect. - ---- - -### Case 1: Missing Block Configuration - -* **Description:** The resource does not define the `blob_properties` block. By default, Azure disables versioning if not specified. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_storage_account" "fail_1" { - name = "storage-insecure-1" - resource_group_name = "rg-prod" - location = "West Europe" - account_tier = "Standard" - account_replication_type = "LRS" - - # The blob_properties block is missing - } - ``` -* **Alert Location:** On the root `azurerm_storage_account` resource. - ---- - -### Case 2: Versioning Explicitly Disabled - -* **Description:** The properties block is included but versioning is turned off, which prevents recovery of modified files. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_storage_account" "fail_2" { - name = "storage-insecure-2" - # ... - blob_properties { - versioning_enabled = false # <-- ISSUE: Disabled. - } - } - ``` -* **Alert Location:** Line `versioning_enabled = false`. - -## Involved Resource - -* `azurerm_storage_account` - -## Solution - -To resolve this risk, ensure you include the `blob_properties` block with the `versioning_enabled` attribute set to `true`. - -```terraform -resource "azurerm_storage_account" "secure_storage" { - name = "storage-secure" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "GRS" - - # SOLUTION: Enable blob versioning - blob_properties { - versioning_enabled = true - } -} From 7626244f04f38b391e5b97ab78e559f9d2836186 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:18 +0100 Subject: [PATCH 129/900] fix(queries): remove undocumented README.md from azure_storage_blob_logging_disabled --- .../README.md | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_blob_logging_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/README.md b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/README.md deleted file mode 100644 index af6a1a5da7e..00000000000 --- a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# KICS Rule: Storage Blob Service Logging Disabled - -## General Description - -This rule verifies that diagnostic logging (**Diagnostic Settings**) is enabled and fully configured for the **Blob** service in Azure storage accounts. - -To ensure complete data plane auditing, it is imperative to log the three fundamental operations that allow tracking the lifecycle of objects: -* **StorageRead:** Audit of blob data reads and container metadata. -* **StorageWrite:** Audit of blob uploads, creations, and modifications. -* **StorageDelete:** Audit of object and container deletions. - -## Rule Logic - -The policy audits the Terraform code by evaluating three compliance levels: -1. **Resource Existence:** Verifies that each `azurerm_storage_account` has an `azurerm_monitor_diagnostic_setting` resource linked to its blob endpoint (`/blobServices/default`). -2. **Log Presence:** Alerts if the diagnostic resource exists but contains no log definitions (`enabled_log`). -3. **Category Integrity:** Analyzes that the `StorageRead`, `StorageWrite`, and `StorageDelete` categories are all present. If the set is incomplete, the alert points directly to the `enabled_log` block. - -## Detected Failure Cases - -### Case 1: Blob Service Without Diagnostic Settings -* **Location:** `azurerm_storage_account`. - -### Case 2: Diagnostic Setting Without Log Blocks -* **Location:** `azurerm_monitor_diagnostic_setting`. - -### Case 3: Incomplete Blob Audit -* **Description:** The log block does not contain the complete set of categories (Read, Write, and Delete). -* **Location:** `enabled_log` block within `azurerm_monitor_diagnostic_setting`. - -## Involved Resources -* `azurerm_storage_account` -* `azurerm_monitor_diagnostic_setting` - -## Solution - -```terraform -resource "azurerm_monitor_diagnostic_setting" "secure_blob_logging" { - name = "blob-audit-complete" - target_resource_id = "${azurerm_storage_account.example.id}/blobServices/default" - storage_account_id = azurerm_storage_account.log_destination.id - - enabled_log { category = "StorageRead" } - enabled_log { category = "StorageWrite" } - enabled_log { category = "StorageDelete" } -} From 77d252b08e9bfc6487d39c7b40f3fad8201a5ef5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:19 +0100 Subject: [PATCH 130/900] fix(queries): remove undocumented README.md from azure_storage_container_immutability_not_locked --- .../README.md | 65 ------------------- 1 file changed, 65 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/README.md diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/README.md b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/README.md deleted file mode 100644 index 6274660fdfd..00000000000 --- a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# KICS Rule: Storage Immutability Policy Not Locked - -## General Description - -This rule verifies that immutability policies (`azurerm_storage_container_immutability_policy`) applied to Azure Storage containers are configured in the **Locked** state (`locked = true`). - -Immutability policies allow data to be stored in a **WORM** (Write Once, Read Many) format. In the context of access control and data protection, there are two critical states: -* **Unlocked (Mutable):** The policy protects data against deletion or modification, but the policy itself can be deleted or modified by users with high privileges. It is a transient state and does not guarantee long-term immutability. -* **Locked (Immutable):** Once locked, the policy becomes irreversible; it cannot be deleted and the retention period can only be increased. This state is a strict integrity control that ensures that not even an administrator can delete data ahead of time. - -## Rule Logic - -The rule audits `azurerm_storage_container_immutability_policy` resources by evaluating two control conditions: -1. **Attribute Omission:** If the `locked` attribute is not defined, Azure assumes the "Unlocked" state by default, allowing the protection to be removed. -2. **Incorrect Value:** If the `locked` attribute is explicitly set to `false`. - -## Detected Failure Cases - -### Case 1: Missing Lock Attribute - -* **Description:** A retention policy is defined but it is not specified whether it should be locked. By default, Azure creates it in the "Unlocked" state. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_storage_container_immutability_policy" "fail_missing" { - storage_container_resource_manager_id = azurerm_storage_container.example.id - retention_period_in_days = 365 - # Missing locked = true - } - ``` -* **Alert Location:** On the root `azurerm_storage_container_immutability_policy` resource. - ---- - -### Case 2: Mutable Policy (Unlocked) - -* **Description:** The `locked` attribute is explicitly set to `false`, which allows the immutability policy to be deleted by authorized users. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_storage_container_immutability_policy" "fail_explicit" { - storage_container_resource_manager_id = azurerm_storage_container.example.id - retention_period_in_days = 730 - locked = false # <-- DETECTED ISSUE - } - ``` -* **Alert Location:** `locked` attribute. - -## Involved Resource - -* `azurerm_storage_container_immutability_policy` - -## Solution - -Set the `locked` attribute to `true` to ensure that the data integrity control is permanent and meets WORM requirements. - -> [!WARNING] -> **Critical Warning:** Once a policy is locked in Azure, **it cannot be deleted**. You will only be able to delete the container once the retention period of all objects has expired. Carefully validate the retention days before applying this change in production. - -```terraform -resource "azurerm_storage_container_immutability_policy" "secure_policy" { - storage_container_resource_manager_id = azurerm_storage_container.example.id - retention_period_in_days = 365 - - # SOLUTION: Policy lock enabled for WORM integrity - locked = true -} From 3bee4b9eef1434dd4fda8cde633af60f840846d6 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:20 +0100 Subject: [PATCH 131/900] fix(queries): remove undocumented README.md from azure_storage_critical_data_cmk_manual --- .../README.md | 62 ------------------- 1 file changed, 62 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/README.md diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/README.md b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/README.md deleted file mode 100644 index 9d65a06794d..00000000000 --- a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# KICS Rule: Critical Data Storage CMK (Manual) - -## General Description - -This rule identifies Azure storage accounts (`azurerm_storage_account`) that use Microsoft-managed encryption (**Platform-Managed Keys**). - -Encryption at rest is automatic in Azure, but using platform-managed keys is not always sufficient to comply with data sovereignty regulations or critical data security requirements. This rule acts as a **manual audit** control: it identifies resources without **Customer-Managed Keys (CMK)** so that the security team can validate whether the contained data (financial, PII, trade secrets) requires the organization to own and manage the encryption keys in their own Key Vault. - -## Rule Logic - -The policy audits the `azurerm_storage_account` resource by evaluating two scenarios: -1. **Missing CMK Configuration:** If the `customer_managed_key` block is not present, the account uses Azure's default keys. -2. **Incomplete Configuration:** If the `customer_managed_key` block exists but does not define the `key_vault_key_id` attribute, CMK encryption is not being effectively applied. - -## Detected Failure Cases - -### Case 1: Data Sensitivity Review Required (Default Encryption) - -* **Description:** The account uses Azure's base encryption. Manual validation is required to determine whether data criticality warrants a move to CMK. -* **Alert Location:** `azurerm_storage_account` resource. - -### Case 2: CMK Block Without Associated Key - -* **Description:** The customer-managed key block has been declared but the cryptographic key identifier has been omitted. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_storage_account" "fail_incomplete" { - name = "stincomplete" - # ... - customer_managed_key { - user_assigned_identity_id = azurerm_user_assigned_identity.example.id - # key_vault_key_id is optional in the schema but required for CMK - } - } - ``` -* **Alert Location:** `customer_managed_key` block. - -## Involved Resource - -* `azurerm_storage_account` - -## Solution - -If the manual review confirms that the data is critical, implement CMK by linking an Azure Key Vault key. - -```terraform -resource "azurerm_storage_account" "secure_critical" { - name = "stcriticaldata" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "GRS" - - identity { - type = "SystemAssigned" - } - - customer_managed_key { - # SOLUTION: Explicitly define the Key Vault key - key_vault_key_id = azurerm_key_vault_key.example.id - } -} From 8e3d4155bba032c3ff89873e645e19a12818daf1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:21 +0100 Subject: [PATCH 132/900] fix(queries): remove undocumented README.md from azure_storage_queue_logging_disabled --- .../README.md | 93 ------------------- 1 file changed, 93 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_queue_logging_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/README.md b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/README.md deleted file mode 100644 index 2657ba596bb..00000000000 --- a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/README.md +++ /dev/null @@ -1,93 +0,0 @@ -# KICS Rule: Storage Queue Service Logging Disabled - -## General Description - -This rule verifies that **Storage Logging** (Storage Analytics Logging) is enabled for the **Queue Service** in Azure storage accounts. - -Audit logging is a fundamental component of observability. It allows detailed activity in the data plane to be tracked, capturing who and when interacted with queue messages. The policy validates that the following operations are recorded: -* **Read:** Operations such as viewing or extracting messages. -* **Write:** Message insertion or update operations. -* **Delete:** Message deletion or queue purge operations. - -Without this configuration, organizations lose the traceability needed to investigate anomalous behavior or information leaks through the messaging service. - -## Rule Logic - -The policy audits both the configuration embedded in the storage account and the specific properties resource: -1. **Attribute Identification:** Looks for the presence of `queue_properties` in the main resource or instances of the standalone resource. -2. **Audit Validation:** Ensures the existence of the `logging` block. -3. **Action Verification:** Checks that `read`, `write`, and `delete` are explicitly configured as `true`. - -## Detected Failure Cases - -The following describes the scenarios that this policy will detect. - ---- - -### Case 1: Missing Embedded Logging - -* **Description:** Queue properties are defined in the storage account but the logging configuration is not included. -* **Alert Location:** `queue_properties` block of the `azurerm_storage_account` resource. - ---- - -### Case 2: Incorrect Embedded Configuration - -* **Description:** The logging block exists in the storage account but one of the critical actions is disabled. -* **Problematic Terraform Code Example:** - ```terraform - resource "azurerm_storage_account" "fail_logging" { - # ... - queue_properties { - logging { - read = false # <-- ISSUE - write = true - delete = true - version = "1.0" - } - } - } - ``` -* **Alert Location:** `logging` attribute of the `azurerm_storage_account` resource. - ---- - -### Case 3: Standalone Resource Without Logging - -* **Description:** The `azurerm_storage_account_queue_properties` resource is used but the logging block is completely omitted. -* **Alert Location:** `azurerm_storage_account_queue_properties` resource. - ---- - -### Case 4: Standalone Resource With Incorrect Configuration - -* **Description:** The standalone properties resource has the logging block, but with disabled actions. -* **Alert Location:** `logging` attribute of the `azurerm_storage_account_queue_properties` resource. - -## Involved Resources - -* `azurerm_storage_account` -* `azurerm_storage_account_queue_properties` - -## Solution - -Enable logging for all operations (`read`, `write`, `delete`) within the queue service configuration. - -```terraform -resource "azurerm_storage_account" "secure_queue" { - name = "stsecurequeue" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - account_tier = "Standard" - account_replication_type = "LRS" - - queue_properties { - logging { - read = true - write = true - delete = true - version = "1.0" - retention_policy_days = 30 - } - } -} From 1fb6965efd21ab3182f84f8497acfe92d703eb75 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:23 +0100 Subject: [PATCH 133/900] fix(queries): remove undocumented README.md from azure_storage_table_logging_disabled --- .../README.md | 52 ------------------- 1 file changed, 52 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_table_logging_disabled/README.md diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/README.md b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/README.md deleted file mode 100644 index 59e0488cdc9..00000000000 --- a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# KICS Rule: Storage Table Service Logging Disabled - -## General Description - -This rule verifies that diagnostic logging (**Diagnostic Settings**) is enabled and fully configured for the **Table Service** in Azure storage accounts. - -Auditing Azure Storage NoSQL tables allows capturing telemetry on who accesses and modifies stored data. The policy ensures that the three essential operation categories are captured for complete traceability: -* **StorageRead:** Audit of entity queries and table metadata reads. -* **StorageWrite:** Audit of data insertions, updates, and upserts. -* **StorageDelete:** Audit of entity deletions or table structure deletions. - -Without these active logs, organizations lack the telemetry needed to identify unauthorized access to sensitive data or investigate errors in NoSQL record manipulation. - -## Rule Logic - -The policy audits the Terraform code by evaluating three compliance levels: -1. **Resource Existence:** Verifies that each `azurerm_storage_account` has an `azurerm_monitor_diagnostic_setting` resource linked to its table endpoint (`/tableServices/default`). -2. **Log Presence:** Alerts if the diagnostic resource exists but the `enabled_log` block is absent. -3. **Category Integrity:** Analyzes that the `StorageRead`, `StorageWrite`, and `StorageDelete` categories are all present simultaneously. If the set is incomplete, the alert points directly to the `enabled_log` block. - -## Detected Failure Cases - -### Case 1: Table Service Without Diagnostic Settings -* **Description:** The storage account has no logging destination configured for tables. -* **Location:** `azurerm_storage_account`. - -### Case 2: Diagnostic Setting Without Log Blocks -* **Description:** The diagnostic resource exists but the log configuration is empty. -* **Location:** `azurerm_monitor_diagnostic_setting`. - -### Case 3: Incomplete Table Audit -* **Description:** One or more critical categories are missing from the log configuration. -* **Location:** `enabled_log` block within `azurerm_monitor_diagnostic_setting`. - -## Involved Resources -* `azurerm_storage_account` -* `azurerm_monitor_diagnostic_setting` - -## Solution - -Configure a complete Diagnostic Setting for the table service. - -```terraform -resource "azurerm_monitor_diagnostic_setting" "secure_table_logging" { - name = "table-audit-complete" - target_resource_id = "${azurerm_storage_account.example.id}/tableServices/default" - storage_account_id = azurerm_storage_account.logs.id - - enabled_log { category = "StorageRead" } - enabled_log { category = "StorageWrite" } - enabled_log { category = "StorageDelete" } -} From dbd91b18ae15dcec985916aced8e671e3d4e6349 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:24 +0100 Subject: [PATCH 134/900] fix(queries): remove undocumented README.md from gcp_access_approval_disabled --- .../gcp_access_approval_disabled/README.md | 50 ------------------- 1 file changed, 50 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_access_approval_disabled/README.md diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/README.md b/assets/queries/terraform/gcp/gcp_access_approval_disabled/README.md deleted file mode 100644 index 2e980f45452..00000000000 --- a/assets/queries/terraform/gcp/gcp_access_approval_disabled/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# KICS Rule: GCP Access Approval Disabled - -## Overview - -This **MEDIUM** severity rule audits compliance with third-party access control in **Google Cloud (GCP)** for `google_project` resources. - -**Access Approval** is an advanced security control that allows organizations to establish an explicit approval step before Google personnel (Engineering or Support) can access customer data. While Google encrypts data by default and restricts access through internal policies, Access Approval grants the customer final sovereignty: any access attempt generates a request via email or Cloud Pub/Sub that the customer must manually approve. - -Without this configuration, it is assumed that Google personnel can access resources for technical support purposes under the standard contract terms, which may not be sufficient for companies subject to strict regulations. - -## Rule Logic - -The policy performs two validations in Terraform code: -1. **Configuration Existence:** Detects if a `google_project` lacks a `google_access_approval_project_settings` resource managing it. -2. **Service Enrollment:** Verifies that, if the configuration exists, it includes at least one `enrolled_services` block. A configuration resource without enrolled services does not actively protect any GCP product. - -## Detected Failure Cases - -The following scenarios will be detected by this policy. - ---- - -### Case 1: Project Without Access Approval -* **Description:** A project is provisioned in GCP but the Google access approval workflow is not implemented. -* **Alert Location:** `google_project` resource block. - -### Case 2: Missing Service Configuration -* **Description:** The Access Approval configuration resource is defined but the protected services block is left empty. -* **Alert Location:** `google_access_approval_project_settings` resource. - -## Resources Involved - -* `google_project` -* `google_access_approval_project_settings` - -## Solution - -Define the configuration resource and ensure the desired services are enrolled (or `all` for full coverage). - -```terraform -resource "google_access_approval_project_settings" "compliant_settings" { - project_id = google_project.my_secure_project.project_id - - enrolled_services { - cloud_product = "all" # Protects all compatible products - enrollment_level = "BLOCK_ALL" - } - - notification_emails = ["security-team@your-company.com"] -} From cfd34301155ff66d8ef65227ec8bd5f605239eb0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:25 +0100 Subject: [PATCH 135/900] fix(queries): remove undocumented README.md from gcp_api_key_api_targets_missing --- .../gcp_api_key_api_targets_missing/README.md | 57 ------------------- 1 file changed, 57 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/README.md diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/README.md b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/README.md deleted file mode 100644 index f3fae1ea44d..00000000000 --- a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# KICS Rule: Google API Key API Targets Missing - -## Overview - -This **MEDIUM** severity rule audits the configuration of **Google API Keys** (`google_apikeys_key`) to ensure access is limited exclusively to the necessary services. - -When an API Key is generated in Google Cloud, it is capable by default of invoking **any enabled API** in the project. This represents a significant security and cost risk; if a key is compromised (for example, by being accidentally exposed in a mobile or web application's source code), an attacker could use it to consume sensitive or high-cost services (such as the Google Maps API or AI models) that are not part of the application's original purpose. - -The security best practice is to apply "API Targets" restrictions so that the key only works with the specific services for which it was created. - -## Rule Logic - -The policy evaluates two failure scenarios in Terraform code: -1. **Absence of Restrictions:** The resource does not define any `restrictions` block, leaving the key completely unprotected. -2. **Missing API Scope:** The resource defines restrictions (such as IPs or referrers), but omits the `api_targets` block, allowing those authorized origins to consume any API in the project. - -## Detected Failure Cases - -The following scenarios will be detected by this policy. - ---- - -### Case 1: Missing Restrictions -* **Description:** The API key is defined without any perimeter or service controls. -* **Alert Location:** `google_apikeys_key` resource block. - -### Case 2: API Targets Not Defined -* **Description:** Client restrictions are applied, but unlimited access to all Google services enabled in the project is maintained. -* **Alert Location:** `restrictions` attribute. - -## Resource Involved - -* `google_apikeys_key` - -## Solution - -Add the `api_targets` block inside the `restrictions` section specifying the required services. - -```terraform -resource "google_apikeys_key" "secure_key" { - name = "production-maps-key" - - restrictions { - # Origin restriction (example for browser) - browser_key_restrictions { - allowed_referrers = ["[https://app.your-company.com/](https://app.your-company.com/)*"] - } - - # Service restriction (Solution) - api_targets { - service = "maps-backend.googleapis.com" - } - api_targets { - service = "places-backend.googleapis.com" - } - } -} From e8c6500adfd1cba05ccc5fc62b7b71c637fba8cb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:26 +0100 Subject: [PATCH 136/900] fix(queries): remove undocumented README.md from gcp_api_key_restrictions_manual --- .../gcp_api_key_restrictions_manual/README.md | 54 ------------------- 1 file changed, 54 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/README.md diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/README.md b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/README.md deleted file mode 100644 index 3f8037b9bbc..00000000000 --- a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# KICS Rule: Google API Key Restrictions (Manual) - -## Overview - -This informational (INFO) rule audits the perimeter security of **Google API Keys** (`google_apikeys_key`). - -Unlike IAM identities, API Keys are not authenticated by a user; they are validated by simple possession. Therefore, it is imperative to restrict their use to specific IP addresses, web domains, or mobile applications. - -This rule ensures that the defense-in-depth principle is applied. Since a static analysis tool cannot determine whether a configured IP address or domain is legitimate or overly permissive, the rule alerts both on the absence of restrictions and on their presence, forcing a manual review of the allowlist. - -## Rule Logic - -The policy evaluates the resource in two stages: -1. **Presence Validation:** If the `restrictions` block is missing, the key is flagged as vulnerable (public access). -2. **Manual Validation:** If the `restrictions` block exists, an informational alert is generated so the auditor can confirm that the values (IPs, referrers, etc.) match the authorized corporate assets. - -## Detected Failure Cases - -The following scenarios will be detected by this policy. - ---- - -### Case 1: No Restrictions (Vulnerable) -* **Description:** The API key lacks client restrictions, allowing anyone with the key to make calls from anywhere on the Internet. -* **Alert Location:** `google_apikeys_key` resource block. - -### Case 2: Restrictions Review (Manual Check) -* **Description:** The key has restrictions configured. The auditor must verify that the defined values are not generic or incorrect. -* **Alert Location:** `restrictions` attribute. - -## Resource Involved - -* `google_apikeys_key` - -## Solution - -Always implement the `restrictions` block using the restriction type that best suits the key's use case (Browser, Server, Android, or iOS). - -```terraform -resource "google_apikeys_key" "secure_api_key" { - name = "frontend-maps-key" - - restrictions { - # Example: Key restricted to a specific domain - browser_key_restrictions { - allowed_referrers = ["[https://app.example.com/](https://app.example.com/)*"] - } - - # Recommended: Combine with API restriction (API Targets) - api_targets { - service = "maps-backend.googleapis.com" - } - } -} From bc34da92ea8bb59965ea29863d28eec570c7aecb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:28 +0100 Subject: [PATCH 137/900] fix(queries): remove undocumented README.md from gcp_app_engine_https_enforcement_manual --- .../README.md | 57 ------------------- 1 file changed, 57 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/README.md diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/README.md b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/README.md deleted file mode 100644 index bd9bb67832d..00000000000 --- a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# KICS Rule: App Engine HTTPS Enforcement (Manual) - -## Overview - -This audit rule verifies that applications deployed on **Google App Engine** (Standard Environment) enforce the exclusive use of encrypted connections via **HTTPS**. - -Serving content over unencrypted HTTP exposes users' confidential data and session credentials to interception. To mitigate this risk, App Engine allows configuring an automatic HTTP to HTTPS redirect. - -Since App Engine typically uses an external configuration file (`app.yaml`) to define network behavior, this rule acts as a governance control that alerts if the policy is not explicitly defined in the infrastructure as code (Terraform) or if it requires manual inspection of deployment artifacts. - -## Rule Logic - -The policy evaluates the `google_app_engine_standard_app_version` resource under two scenarios: -1. **Terraform Configuration:** If the `handlers` block is present, it ensures that the `security_level` attribute is configured as `SECURE_ALWAYS`. Any other value (such as `SECURE_OPTIONAL`) will trigger an alert. -2. **External Configuration:** If no `handlers` are defined in Terraform, the rule generates an informational alert (**INFO**) indicating that compliance depends on the configuration within the application's `app.yaml` file. - -## Detected Failure Cases - -The following scenarios will be detected by this policy. - ---- - -### Case 1: Insecure Security Level in Terraform -* **Description:** URL handlers allow HTTP traffic or do not enforce secure redirection. -* **Alert Location:** `handlers` attribute within the App Engine resource. - -### Case 2: Manual Verification of Configuration Files -* **Description:** Terraform does not manage routing logic. The source code must be validated. -* **Required Action:** Confirm that in `app.yaml` all critical handlers contain: - ```yaml - secure: always - ``` -* **Alert Location:** `google_app_engine_standard_app_version` resource level. - -## Resource Involved - -* `google_app_engine_standard_app_version` - -## Solution - -To enforce HTTPS from Terraform, configure `security_level` in each handler: - -```terraform -resource "google_app_engine_standard_app_version" "secure_app" { - service = "api-service" - version_id = "v2" - runtime = "nodejs18" - - handlers { - url_regex = "/.*" - script { - script_path = "auto" - } - # Technical solution - security_level = "SECURE_ALWAYS" - } -} From 05d97c4990d1fd01c314b5571f240904d004e398 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:29 +0100 Subject: [PATCH 138/900] fix(queries): remove undocumented README.md from gcp_compute_logging_service_disabled --- .../README.md | 49 ------------------- 1 file changed, 49 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/README.md diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/README.md b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/README.md deleted file mode 100644 index d0c6b8394cf..00000000000 --- a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# KICS Rule: GCP Compute Logging Service Disabled - -## Overview - -This **Observability** rule verifies that **Google Compute Engine** instances (`google_compute_instance`) have logging to the **Cloud Logging** service enabled via the `google-logging-enabled` metadata key. - -Visibility is a critical security component. The Google Cloud agent (Ops Agent) uses this flag to determine whether to transmit operating system and application logs to the centralized Google Cloud console. Without these logs, intrusion detection, forensic analysis, and resolution of operational errors become impractical tasks. - -## Rule Logic - -The policy audits the resource by evaluating three possible failure states to maximize reporting accuracy: -1. **Missing Block:** If the entire `metadata` block is absent. -2. **Missing Key:** If the `metadata` block exists but does not define the required key. -3. **Incorrect Value:** If the key exists but has been explicitly set to `"false"`. - -## Detected Failure Cases - ---- - -### Case 1: Missing Metadata Configuration -* **Description:** The instance does not define any metadata, therefore omitting the logging service. -* **Alert Location:** `google_compute_instance` resource level. - -### Case 2: Missing Logging Flag -* **Description:** Metadata is used but `google-logging-enabled` is specifically omitted. -* **Alert Location:** `metadata` attribute. - -### Case 3: Logging Disabled -* **Description:** The value `"false"` has been configured, actively blocking log ingestion. -* **Alert Location:** `google-logging-enabled` attribute. - -## Resource Involved - -* `google_compute_instance` - -## Solution - -Ensure the metadata is set to `"true"` to enable the service. - -```terraform -resource "google_compute_instance" "secure_vm" { - name = "prod-server" - machine_type = "e2-medium" - zone = "us-central1-a" - - metadata = { - "google-logging-enabled" = "true" - } -} From a4167fc19e52fb028d8955fbae82acd42dfcdf4b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:30 +0100 Subject: [PATCH 139/900] fix(queries): remove undocumented README.md from gcp_gke_default_service_account_used --- .../README.md | 51 ------------------- 1 file changed, 51 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_default_service_account_used/README.md diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/README.md b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/README.md deleted file mode 100644 index 467b528e1b2..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# KICS Rule: GKE Default Service Account Used - -## Overview - -This **HIGH** severity rule verifies that **Google Kubernetes Engine (GKE)** clusters and node pools do not use the default Compute Engine service account. - -By default, if the `service_account` attribute is not specified, GKE uses the project's default service account (`PROJECT_NUMBER-compute@developer.gserviceaccount.com`). This account automatically has the **Editor** role, which grants nodes (and potentially Pods) extensive permissions to modify resources in GCP, such as storage buckets, VPC networks, and other instances. Using a dedicated service account with minimal privileges drastically reduces the "blast radius" in the event of a security compromise in the cluster. - -## Rule Logic - -The policy audits the `google_container_cluster` and `google_container_node_pool` resources under the following criteria: -1. **Missing Attribute:** Identifies if the `node_config` block lacks the `service_account` key. -2. **Risk Identification:** The alert is triggered upon detecting that the cluster will delegate its identity to the project's most privileged service account by default. - -## Detected Failure Cases - ---- - -### Case 1: Implicit Use in Cluster -* **Description:** A GKE cluster is defined without specifying an identity for the nodes. -* **Alert Location:** `node_config` attribute of the `google_container_cluster` resource. - -### Case 2: Implicit Use in Node Pool -* **Description:** An additional node pool is created that inherits the default service account. -* **Alert Location:** `node_config` attribute of the `google_container_node_pool` resource. - -## Resources Involved - -* `google_container_cluster` -* `google_container_node_pool` - -## Solution - -Create a custom Service Account with the minimum necessary permissions (e.g., logging, monitoring, and registry access roles) and assign it explicitly. - -```terraform -resource "google_service_account" "gke_nodes_sa" { - account_id = "gke-nodes-identity" - display_name = "GKE Nodes Minimal Service Account" -} - -resource "google_container_cluster" "secure_cluster" { - name = "production-cluster" - location = "us-central1" - - node_config { - # Solution: Dedicated identity - service_account = google_service_account.gke_nodes_sa.email - oauth_scopes = ["[https://www.googleapis.com/auth/cloud-platform](https://www.googleapis.com/auth/cloud-platform)"] - } -} From 32feafd0684224c6c7b37a2a938c99e212e68109 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:31 +0100 Subject: [PATCH 140/900] fix(queries): remove undocumented README.md from gcp_gke_image_vulnerability_scanning_disabled --- .../README.md | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/README.md diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/README.md b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/README.md deleted file mode 100644 index 647e3bc06ea..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# KICS Rule: GKE Image Vulnerability Scanning Disabled - -## Overview - -This **HIGH** severity rule verifies that automatic vulnerability scanning is enabled in **Google Kubernetes Engine (GKE)** clusters through the Security Posture Dashboard. - -Enabling vulnerability scanning allows GKE to continuously inspect the container images running in the cluster's workloads. GKE compares container OS packages against public vulnerability databases (CVEs). Without this feature active, the organization lacks visibility into whether deployed applications contain known security flaws that could be exploited by attackers. - -## Rule Logic - -The policy audits the `google_container_cluster` resource by evaluating three risk states: -1. **Configuration Omission:** The cluster does not have the `security_posture_config` block defined. -2. **Unspecified Mode:** The block exists but does not define the `vulnerability_mode` parameter. -3. **Explicit Disabling:** The `vulnerability_mode` parameter is configured as `VULNERABILITY_DISABLED`. - -## Detected Failure Cases - ---- - -### Case 1: Missing Security Posture Configuration -* **Description:** The cluster is provisioned with Google's default configuration, which does not always include active advanced scanning. -* **Alert Location:** `google_container_cluster` resource level. - -### Case 2: Vulnerability Mode Missing or Disabled -* **Description:** The security configuration is defined but image scanning is omitted or explicitly disabled. -* **Alert Location:** `vulnerability_mode` attribute within `security_posture_config`. - -## Resource Involved - -* `google_container_cluster` - -## Solution - -Enable scanning by configuring the `security_posture_config` block with a valid vulnerability mode. - -```terraform -resource "google_container_cluster" "compliant_cluster" { - name = "secure-production-cluster" - location = "us-central1" - - # Recommended solution - security_posture_config { - mode = "BASIC" - vulnerability_mode = "VULNERABILITY_BASIC" - } -} From 60a9ca9f023e9cf9c17b900b7295e2d4a688eead Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:33 +0100 Subject: [PATCH 141/900] fix(queries): remove undocumented README.md from gcp_gke_manual_iam_check --- .../gcp/gcp_gke_manual_iam_check/README.md | 38 ------------------- 1 file changed, 38 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_manual_iam_check/README.md diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/README.md b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/README.md deleted file mode 100644 index 6b96716f89c..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# KICS Rule: GKE Service Account IAM Review (Manual) - -## Overview - -This informational (INFO) **Supply Chain** rule audits the identities used by **Google Kubernetes Engine (GKE)** nodes when custom service accounts have been configured. - -Using custom service accounts is the first step toward the principle of least privilege. However, if this account is assigned roles with write permissions (such as `roles/artifactregistry.writer` or `roles/storage.objectAdmin`), an attacker who compromises a node could modify or replace container images in the registry. This would enable persistence or privilege escalation attacks in other clusters that consume those same images. - -## Rule Logic - -The policy identifies `google_container_cluster` and `google_container_node_pool` resources that explicitly define a `service_account`. As a manual check, it generates an informational alert on the service account line so the auditor can validate in the GCP project that the associated roles are exclusively **Read-Only**. - -## Detected Failure Cases - ---- - -### Case 1: SA Review in Cluster -* **Description:** A custom identity has been defined for the cluster. It must be verified that it does not have "Push" permissions to the image registry. -* **Alert Location:** `service_account` attribute in `google_container_cluster`. - -### Case 2: SA Review in Node Pool -* **Description:** A specific node pool uses its own identity that requires IAM role auditing. -* **Alert Location:** `service_account` attribute in `google_container_node_pool`. - -## Resources Involved - -* `google_container_cluster` -* `google_container_node_pool` - -## Solution - -Ensure that the assigned Service Account only has read roles for the image registry used. - -**Recommended Roles:** -* `roles/artifactregistry.reader` (for Artifact Registry) -* `roles/storage.objectViewer` (for Container Registry/GCR) -* `roles/logging.logWriter` -* `roles/monitoring.metricWriter` From db3de88d555ff42ce5e98793372f4796140c64b1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:34 +0100 Subject: [PATCH 142/900] fix(queries): remove undocumented README.md from gcp_gke_metadata_server_disabled --- .../README.md | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/README.md diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/README.md b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/README.md deleted file mode 100644 index d74f643dd65..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# KICS Rule: GKE Metadata Server Disabled - -## Overview - -This **HIGH** severity rule verifies that GKE nodes use the **GKE Metadata Server** to manage workload identities. - -By default, GKE nodes have access to the Compute Engine (GCE) metadata server, which exposes sensitive host information and node service account access tokens. If an attacker manages to compromise a pod, they could query this endpoint to obtain credentials and perform lateral movement to other project resources. By enabling `GKE_METADATA`, the bridge to **Workload Identity** is activated, intercepting these requests and limiting access to only what the Pod is specifically permitted. - -## Rule Logic - -The policy audits the `google_container_cluster` and `google_container_node_pool` resources under two criteria: -1. **Block Omission:** Verifies if `workload_metadata_config` is present within `node_config`. -2. **Insecure Mode:** Ensures that the `mode` attribute is strictly `GKE_METADATA`. The value `GCE_METADATA` (legacy default value) is considered vulnerable. - -## Detected Failure Cases - ---- - -### Case 1: Missing Metadata Configuration -* **Description:** The cluster or node pool does not define the workload metadata mode. -* **Alert Location:** `node_config` attribute. - -### Case 2: Use of GCE_METADATA (Legacy/Vulnerable) -* **Description:** Pods are explicitly allowed access to the underlying compute instance metadata. -* **Alert Location:** `mode` attribute within `workload_metadata_config`. - -## Resources Involved - -* `google_container_cluster` -* `google_container_node_pool` - -## Solution - -Configure the `workload_metadata_config` block with the `GKE_METADATA` mode. - -```terraform -resource "google_container_node_pool" "compliant_pool" { - name = "secure-pool" - cluster = google_container_cluster.primary.name - - node_config { - # Technical solution - workload_metadata_config { - mode = "GKE_METADATA" - } - } -} From ccc13fb625573e7c08105b93d85860edb7e8d784 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:35 +0100 Subject: [PATCH 143/900] fix(queries): remove undocumented README.md from gcp_gke_sandbox_disabled --- .../gcp/gcp_gke_sandbox_disabled/README.md | 52 ------------------- 1 file changed, 52 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/README.md diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/README.md b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/README.md deleted file mode 100644 index 7648709eada..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# KICS Rule: GKE Sandbox (gVisor) Disabled - -## Overview - -This **LOW** severity rule verifies whether GKE node pools have **GKE Sandbox (gVisor)** enabled for enhanced isolation. - -GKE Sandbox uses **gVisor**, a user-space kernel that provides an additional security barrier between applications and the host kernel. By intercepting and filtering system calls, gVisor mitigates the risk of container escape attacks, where a malicious process attempts to compromise the underlying node. Although gVisor introduces a slight performance overhead, omitting it in environments that run untrusted code or multi-tenant applications is an **Insecure Configuration**. - -## Rule Logic - -The policy audits the `google_container_cluster` and `google_container_node_pool` resources: -1. **Block Omission:** Detects if `sandbox_config` is not present in `node_config`. -2. **Incorrect Type:** Verifies that `sandbox_type` is explicitly `"gvisor"`. - -## Detected Failure Cases - ---- - -### Case 1: Sandbox Not Configured in Cluster -* **Description:** The cluster's default nodes do not use gVisor isolation. -* **Alert Location:** `node_config` attribute. - -### Case 2: Sandbox Not Configured in Node Pool -* **Description:** An additional node pool has been created that lacks Sandbox protection. -* **Alert Location:** `node_config` attribute. - -### Case 3: Insecure Sandbox Type -* **Description:** The block is defined but a value other than `gvisor` is used, disabling the intended protection. -* **Alert Location:** `sandbox_type` attribute. - -## Resources Involved - -* `google_container_cluster` -* `google_container_node_pool` - -## Solution - -Enable gVisor ensuring the compatible `COS_CONTAINERD` image type is used. - -```terraform -resource "google_container_node_pool" "secure_pool" { - name = "untrusted-code-pool" - cluster = google_container_cluster.primary.name - - node_config { - image_type = "COS_CONTAINERD" - - sandbox_config { - sandbox_type = "gvisor" - } - } -} From a7adea598bbe763ad9b32ebc5827079f18c18f8d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:36 +0100 Subject: [PATCH 144/900] fix(queries): remove undocumented README.md from gcp_gke_secrets_encryption_cmek_disabled --- .../README.md | 50 ------------------- 1 file changed, 50 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/README.md diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/README.md b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/README.md deleted file mode 100644 index 88394f37d3c..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# KICS Rule: GKE Secrets Not Encrypted with CMEK - -## Overview - -This **HIGH** severity rule verifies that GKE clusters have application-layer secret encryption enabled using a customer-managed **Cloud KMS** key (**CMEK**). - -By default, GKE encrypts data at rest at the disk level, but Kubernetes secrets stored in the `etcd` database require an additional layer of protection. By enabling this feature, GKE uses envelope encryption where a Data Encryption Key (DEK) encrypts the secret, and that DEK is encrypted by a Key Encryption Key (KEK) hosted in Cloud KMS. This allows the customer to have absolute sovereignty over their secrets, being able to revoke access to them instantly by disabling the key in KMS. - -## Rule Logic - -The policy audits the `google_container_cluster` resource by evaluating three security failures: -1. **Omission:** The `database_encryption` block is not defined. -2. **Disabling:** The encryption state is explicitly set to `DECRYPTED`. -3. **Incomplete Configuration:** Encryption is activated but the key identifier (`key_name`) is not provided. - -## Detected Failure Cases - ---- - -### Case 1: Missing Encryption Configuration -* **Description:** The cluster is provisioned without the protection layer for secrets in etcd. -* **Alert Location:** `google_container_cluster` resource block. - -### Case 2: Encryption Disabled -* **Description:** The block is configured but the state is marked as unencrypted. -* **Alert Location:** `state` attribute within `database_encryption`. - -### Case 3: Missing KMS Key -* **Description:** Encryption is attempted but no valid Cloud KMS key is referenced. -* **Alert Location:** `key_name` attribute within `database_encryption`. - -## Resource Involved - -* `google_container_cluster` - -## Solution - -Configure the `database_encryption` block with the `ENCRYPTED` state and assign the corresponding key resource. - -```terraform -resource "google_container_cluster" "secure_cluster" { - name = "production-cluster" - location = "us-central1" - - # Technical solution - database_encryption { - state = "ENCRYPTED" - key_name = "projects/my-project/locations/global/keyRings/my-ring/cryptoKeys/my-key" - } -} From 88969261950892b32bc07ebe4ce12366446d91a2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:38 +0100 Subject: [PATCH 145/900] fix(queries): remove undocumented README.md from gcp_gke_security_posture_manual --- .../gcp_gke_security_posture_manual/README.md | 45 ------------------- 1 file changed, 45 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/README.md diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/README.md b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/README.md deleted file mode 100644 index 1539f0aa785..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# KICS Rule: GKE Security Posture Disabled (Manual) - -## Overview - -This informational (**INFO**) **Observability** rule verifies whether the GKE **Security Posture Dashboard** is active in the cluster configuration. - -The security posture dashboard is a native Google Cloud tool that automatically scans Kubernetes workloads for common misconfigurations and known vulnerabilities in container images. It provides actionable recommendations to improve security without adding operational complexity. Since the availability of this feature may vary depending on the GKE version channel and license type (Standard vs Autopilot), this rule alerts on its absence to allow a manual compatibility check. - -## Rule Logic - -The policy audits the `google_container_cluster` resource identifying two scenarios: -1. **Omission:** The `security_posture_config` block is not present in the Terraform code. -2. **Disabling:** The block exists but the `mode` parameter has been explicitly set to `DISABLED`. - -## Detected Failure Cases - ---- - -### Case 1: Missing Posture Configuration -* **Description:** The cluster has not enabled the security control dashboard. It is recommended to verify whether the GKE version allows its activation. -* **Alert Location:** `google_container_cluster` resource level. - -### Case 2: Posture Mode Disabled -* **Description:** The security posture has been configured but disabled using the `DISABLED` value. -* **Alert Location:** `mode` attribute within `security_posture_config`. - -## Resource Involved - -* `google_container_cluster` - -## Solution - -Enable the security posture by setting the mode to `BASIC` or `ENTERPRISE`. - -```terraform -resource "google_container_cluster" "compliant_cluster" { - name = "monitored-cluster" - location = "us-central1" - - # Recommended solution for security observability - security_posture_config { - mode = "BASIC" - vulnerability_mode = "VULNERABILITY_BASIC" - } -} From c80aa40066512fb135f0dc9906ec9d7c38fd9554 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:39 +0100 Subject: [PATCH 146/900] fix(queries): remove undocumented README.md from gcp_gke_workload_identity_manual --- .../README.md | 54 ------------------- 1 file changed, 54 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/README.md diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/README.md b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/README.md deleted file mode 100644 index 187d8039f8f..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# KICS Rule: GKE Workload Identity & Dedicated SA (Manual) - -## Overview - -This informational (**INFO**) **Access Control** rule audits the identity configuration for workloads running in **Google Kubernetes Engine (GKE)**. - -The security best practice for GKE applications to access Google Cloud services (such as Cloud Storage or BigQuery) is to use **Workload Identity**. This functionality eliminates the need to download and manage JSON service account keys by securely binding a Kubernetes Service Account (KSA) with a Google Service Account (GSA). - -However, enabling the feature is only half the work. A secure configuration requires a **1:1** mapping; if multiple applications share the same Google identity, a compromise in one of them would grant lateral access to the resources of the others. - -## Rule Logic - -The policy audits the `google_container_cluster` resource in two phases: -1. **Feature Validation:** Detects if `workload_identity_config` is absent, which forces Pods to use the node identity (high risk). -2. **Governance Audit:** If the feature is active, it alerts the auditor to manually verify in the code that each microservice has its own dedicated binding. - -## Detected Failure Cases - ---- - -### Case 1: Workload Identity Disabled -* **Description:** The cluster lacks the infrastructure necessary for granular identities. -* **Alert Location:** `google_container_cluster` resource level. - -### Case 2: Identity Mapping Review -* **Description:** The functionality is active, but it must be confirmed that service accounts are not being shared between different microservices. -* **Alert Location:** `workload_identity_config` block. - -## Resource Involved - -* `google_container_cluster` - -## Solution - -1. Enable Workload Identity in your cluster resource. -2. Implement granular bindings using the `roles/iam.workloadIdentityUser` role. - -```terraform -resource "google_container_cluster" "compliant_cluster" { - name = "secure-cluster" - location = "us-central1" - - # Enable the feature - workload_identity_config { - workload_pool = "${var.project_id}.svc.id.goog" - } -} - -# Example of manual binding to verify (1:1 Mapping) -resource "google_service_account_iam_member" "dedicated_binding" { - service_account_id = google_service_account.app_specific_sa.name - role = "roles/iam.workloadIdentityUser" - member = "serviceAccount:${var.project_id}.svc.id.goog[namespace/ksa-name]" -} From 54781a1ac9781cefc4b60d35136bc388fc3b8277 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:40 +0100 Subject: [PATCH 147/900] fix(queries): remove undocumented README.md from gcp_http_load_balancer_logging_disabled --- .../README.md | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/README.md diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/README.md b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/README.md deleted file mode 100644 index 6f849db7f85..00000000000 --- a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# KICS Rule: GCP HTTP(S) Load Balancer Logging Disabled - -## Overview - -This **MEDIUM** severity rule verifies that access logging (Logging) is enabled in `google_compute_backend_service` resources in Google Cloud. - -Backend Services manage the traffic that the HTTP(S) load balancer distributes to instance groups or buckets. Enabling Cloud Armor and load balancer logs allows capturing critical metadata for each HTTP transaction: source IP address, protocols, response latencies, and status codes (2xx, 4xx, 5xx). Without these logs, incident response capability for security events (such as DoS attacks or injections) and debugging of infrastructure errors are severely limited. - -## Rule Logic - -The policy audits the `google_compute_backend_service` resource under two criteria: -1. **Omission:** Detects if the `log_config` block has not been defined. -2. **Disabling:** Detects if the `enable` attribute within `log_config` has the boolean value `false`. - -## Detected Failure Cases - ---- - -### Case 1: Missing Logging Configuration -* **Description:** The backend service is created without logging parameters, which disables traffic telemetry by default. -* **Alert Location:** `google_compute_backend_service` resource level. - -### Case 2: Logging Explicitly Disabled -* **Description:** The configuration block is defined but the log service is turned off. -* **Alert Location:** `enable` attribute within `log_config`. - -## Resource Involved - -* `google_compute_backend_service` - -## Solution - -Add the `log_config` block with the `enable = true` parameter. A `sample_rate` of `1.0` is recommended for production. - -```terraform -resource "google_compute_backend_service" "compliant_service" { - name = "web-backend-service" - protocol = "HTTP" - port_name = "http" - timeout_sec = 10 - - # Technical solution - log_config { - enable = true - sample_rate = 1.0 - } -} From e902a38a0c38e102ed26d02e93cff32e7025742d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:41 +0100 Subject: [PATCH 148/900] fix(queries): remove undocumented README.md from gcp_iap_backend_service_disabled --- .../README.md | 53 ------------------- 1 file changed, 53 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/README.md diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/README.md b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/README.md deleted file mode 100644 index 1c8ec66888c..00000000000 --- a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# KICS Rule: IAP Disabled on Backend Service - -## Overview - -This rule verifies that **Identity-Aware Proxy (IAP)** is enabled in `google_compute_backend_service` resources. - -IAP is a Zero Trust security component that intercepts web requests sent to your application, authenticates the user via their Google identity, and only allows the request through if the user is authorized. - -**Note on Firewall (Manual):** -Enabling IAP is only the first step. To fully comply with the security policy ("Allow only Google traffic"), you must manually configure your VPC firewall rules to allow traffic **only** from Google load balancer IP ranges (`130.211.0.0/22` and `35.191.0.0/16`) to your instances, blocking all direct traffic from the Internet. - -## Rule Logic - -The policy audits the `google_compute_backend_service` resource: -1. Verifies whether the `iap` configuration block exists. -2. If the block does not exist, the service is considered unprotected by identity. -3. Verifies that, if the block exists, the required credentials (`oauth2_client_id` and `oauth2_client_secret`) are defined. - -## Detected Failure Cases - -### Case 1: IAP Disabled - -* **Description:** The backend service has been defined without the `iap` block, meaning traffic arrives directly (or through the standard LB) without prior identity verification by IAP. -* **Alert Location:** `google_compute_backend_service` resource. - -### Case 2: Missing OAuth Client ID - -* **Description:** The `iap` block is present but omits the `oauth2_client_id`, preventing authentication. -* **Alert Location:** `iap` block. - -### Case 3: Missing OAuth Client Secret - -* **Description:** The `iap` block is present but omits the `oauth2_client_secret`, preventing authentication. -* **Alert Location:** `iap` block. - -## Resource Involved - -* `google_compute_backend_service` - -## Solution - -Define the `iap` block within the backend service and include the required OAuth credentials. - -```terraform -resource "google_compute_backend_service" "secure" { - name = "iap-backend-service" - health_checks = [google_compute_health_check.default.id] - - iap { - oauth2_client_id = "abc-123.apps.googleusercontent.com" - oauth2_client_secret = "secret-key" - } -} From 31d781013ca276c564664be84583d5939f3b4819 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:42 +0100 Subject: [PATCH 149/900] fix(queries): remove undocumented README.md from gcp_sql_postgresql_log_error_verbosity_verbose --- .../README.md | 40 ------------------- 1 file changed, 40 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/README.md diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/README.md b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/README.md deleted file mode 100644 index d9596f65279..00000000000 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# KICS Rule: Cloud SQL PostgreSQL log_error_verbosity is Verbose - -## Overview - -This rule verifies the configuration of the `log_error_verbosity` database flag in **Google Cloud SQL (PostgreSQL)** instances. - -This parameter controls the amount of detail written to the server error log. The `verbose` level includes internal information such as source code and line numbers, which is not recommended for production environments for security and performance reasons. - -## Rule Logic - -The policy inspects the `google_sql_database_instance` resource: -1. Verifies if the database version contains "POSTGRES". -2. Normalizes the `settings.database_flags` block to correctly process configurations with both single and multiple flags. -3. If it finds a flag named `log_error_verbosity` with the value `verbose`, it generates an alert. - -## Detected Failure Cases - -### Case 1: Insecure Verbosity - -* **Description:** The flag is explicitly configured as `verbose`. -* **Alert Location:** `database_flags` block. - -## Resource Involved - -* `google_sql_database_instance` - -## Solution - -Set the value to `default`, `terse`, or remove the flag. - -```terraform -resource "google_sql_database_instance" "secure" { - database_version = "POSTGRES_14" - settings { - database_flags { - name = "log_error_verbosity" - value = "default" - } - } -} From 6dd2cfe950e5ef6c6d84460131d87fc7c8769958 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:44 +0100 Subject: [PATCH 150/900] fix(queries): remove undocumented README.md from gcp_sql_postgresql_log_statement_improperly_set --- .../README.md | 51 ------------------- 1 file changed, 51 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/README.md diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/README.md b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/README.md deleted file mode 100644 index 3e6b362bca9..00000000000 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# KICS Rule: Cloud SQL PostgreSQL log_statement Improperly Set - -## Overview - -This rule verifies the configuration of the `log_statement` flag in **Google Cloud SQL (PostgreSQL)** instances. - -This parameter controls which SQL statements are logged in the server logs: -* **`none`:** Does not log any statements (Default). -* **`ddl`:** Logs data definition statements (CREATE, ALTER, DROP). Recommended by CIS Benchmark as a baseline. -* **`mod`:** Logs DDL and data modification statements (INSERT, UPDATE, DELETE). -* **`all`:** Logs all statements. - -To comply with audit and security regulations, it must be configured to at least `ddl` to track structural changes in the database that could compromise its integrity. - -## Rule Logic - -The policy evaluates the `google_sql_database_instance` resource (PostgreSQL): -1. **Missing Flag:** If `log_statement` is not found within the list of configured flags, it fails (since PostgreSQL's default value is insufficient for auditing). -2. **Incorrect Flag:** If `log_statement` is present but its value is explicitly `none`, it fails. - -## Detected Failure Cases - -### Case 1: Missing Configuration -* **Description:** The flag has not been defined, so the database is not auditing critical statements. -* **Alert Location:** `database_flags` block. - -### Case 2: Auditing Explicitly Disabled -* **Description:** The flag is configured with the value `none`, disabling statement logging. -* **Alert Location:** `database_flags` block. - -## Resource Involved - -* `google_sql_database_instance` - -## Solution - -Set the value of the `log_statement` flag to `ddl` (minimum recommended for auditing), `mod`, or `all`. - -```terraform -resource "google_sql_database_instance" "secure" { - name = "secure-postgresql" - database_version = "POSTGRES_14" - region = "us-central1" - - settings { - database_flags { - name = "log_statement" - value = "ddl" - } - } -} From 6763b3a01ad4ade5c34fa383b263d58a19d8acbb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:45 +0100 Subject: [PATCH 151/900] fix(queries): remove undocumented README.md from ibm_activity_tracker_global_events_disabled --- .../README.md | 65 ------------------- 1 file changed, 65 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/README.md diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/README.md b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/README.md deleted file mode 100644 index e0bac430cd4..00000000000 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# Regla KICS: Log de Auditoría para IBM Cloud IAM (Activity Tracker) - -## Descripción General - -Esta regla de KICS para Terraform asegura que una instancia de IBM Cloud Activity Tracker esté configurada para capturar eventos de auditoría, especialmente los eventos globales relacionados con la gestión de identidades y accesos (IAM). - -IBM Cloud genera eventos de auditoría para acciones críticas en la cuenta (creación de usuarios, cambios de políticas, etc.). Para que estos eventos sean registrados y retenidos, se debe provisionar un servicio `activity-tracker`. Además, para capturar eventos que ocurren a nivel de cuenta (globales), la instancia de Activity Tracker debe estar ubicada en una región específica designada por IBM como "región de eventos globales". Sin esta configuración, las acciones de los administradores sobre IAM podrían no quedar registradas, dificultando investigaciones forenses o auditorías de cumplimiento. - -## Lógica de la Regla - -La política se compone de dos reglas que verifican la configuración de Activity Tracker: -1. **Validación Global:** Confirma que al menos una instancia de `activity-tracker` exista en la configuración. -2. **Validación de Ubicación:** Si existen instancias, confirma que su atributo `location` corresponda a una región compatible con eventos globales. Las regiones soportadas son: `eu-de` (Frankfurt), `eu-gb` (Londres), `us-south` (Dallas) y `au-syd` (Sídney). - -## Casos de Fallo Detectados - -A continuación se describen los dos escenarios que esta política detectará. - ---- - -### Caso 1: Instancia de `activity-tracker` Ausente - -* **Descripción:** Esta regla se activa si no existe ningún recurso `ibm_resource_instance` en la configuración de Terraform que tenga el atributo `service` configurado como `"activity-tracker"`. Esto significa que no se está capturando ningún log de auditoría en la cuenta. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - # El proyecto contiene varios recursos, pero ninguno define el servicio 'activity-tracker'. - resource "ibm_is_vpc" "example" { - name = "my-vpc" - } - ``` -* **Ubicación de la Alerta:** La alerta será general y se anclará al bloque `provider "ibm" {}` indicando la ausencia del recurso. - ---- - -### Caso 2: Instancia en una Región de Eventos Globales Incorrecta - -* **Descripción:** Esta regla se activa si el recurso `activity-tracker` tiene su atributo `location` configurado en una región que no está designada por IBM para recibir eventos globales. Esto resultaría en la pérdida de visibilidad sobre los eventos de IAM. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_resource_instance" "activity_tracker_wrong_region" { - name = "my-activity-tracker" - service = "activity-tracker" - plan = "lite" - location = "us-east" # <-- ¡PROBLEMA! No es una región de eventos globales. - } - ``` -* **Ubicación de la Alerta:** La alerta señalará específicamente al atributo `location` de la instancia de Activity Tracker incorrecta. - -## Recurso Involucrado - -* `ibm_resource_instance` - -## Solución - -Para solucionar los problemas detectados, asegúrate de que exista al menos un recurso `ibm_resource_instance` para el servicio `activity-tracker` y que su atributo `location` esté configurado en una de las regiones de eventos globales soportadas (Frankfurt, Londres, Dallas o Sídney). - -```terraform -resource "ibm_resource_instance" "activity_tracker_correct" { - name = "my-global-activity-tracker" - service = "activity-tracker" - plan = "lite" - - # 'eu-de' es una de las regiones que soportan eventos globales. - location = "eu-de" -} \ No newline at end of file From fb8f2333954c542739952d82e6bbe465b29a0e6d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:46 +0100 Subject: [PATCH 152/900] fix(queries): remove undocumented README.md from ibm_activity_tracker_platform_logs_disabled --- .../README.md | 86 ------------------- 1 file changed, 86 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/README.md diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/README.md b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/README.md deleted file mode 100644 index 8bb0d4d359e..00000000000 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# Regla KICS: Logs de Plataforma Habilitados en Activity Tracker - -## Descripción General - -Esta regla de KICS para Terraform asegura que el servicio IBM Cloud Activity Tracker esté configurado para recibir y registrar los logs de gestión de la plataforma. - -Los logs de plataforma (`platform_logs`) capturan eventos críticos a nivel de cuenta, como la gestión de usuarios y accesos (IAM), la facturación y la modificación de recursos, que son esenciales para una auditoría de seguridad completa y el cumplimiento normativo. Si esta opción no está habilitada, se pierde visibilidad sobre las acciones más importantes que ocurren en la cuenta, dejando puntos ciegos en la monitorización de seguridad. - -## Lógica de la Regla - -La política se divide en tres reglas especializadas para cubrir todos los escenarios en los que los logs de plataforma no están habilitados: -1. **Existencia Global:** Verifica que al menos un Activity Tracker esté provisionado en la cuenta. -2. **Atributo Faltante:** Verifica que el atributo `platform_logs` esté definido (ya que por defecto es `false`). -3. **Valor Incorrecto:** Verifica que el atributo no esté explícitamente desactivado. - -## Casos de Fallo Detectados - -A continuación se describen los tres escenarios que esta política detectará. - ---- - -### Caso 1: Instancia de `activity-tracker` Ausente - -* **Descripción:** Esta regla se activa si no existe ningún recurso `ibm_resource_instance` con `service = "activity-tracker"`. Sin esta instancia, no hay ningún servicio que pueda recopilar los logs de la plataforma. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - # El proyecto de Terraform no define ninguna instancia para el servicio 'activity-tracker'. - resource "ibm_is_vpc" "example" { - name = "my-vpc" - } - ``` -* **Ubicación de la Alerta:** La alerta será general y se anclará al bloque `provider "ibm" {}` para indicar que falta un recurso `activity-tracker` en la configuración global. - ---- - -### Caso 2: Atributo `platform_logs` Ausente - -* **Descripción:** Esta regla detecta una instancia de `activity-tracker` que existe, pero a la que le falta el atributo `platform_logs`. Según la documentación de Terraform para IBM Cloud, el valor por defecto de este atributo es `false`, por lo que su ausencia constituye una configuración insegura. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_resource_instance" "tracker_missing_attribute" { - name = "my-activity-tracker" - service = "activity-tracker" - plan = "lite" - location = "eu-de" - - # El atributo 'platform_logs' no está presente. - } - ``` -* **Ubicación de la Alerta:** La alerta señalará directamente al bloque del recurso `ibm_resource_instance` al que le falta el atributo. - ---- - -### Caso 3: Atributo `platform_logs` es `false` - -* **Descripción:** Esta regla busca una instancia de `activity-tracker` que tiene el atributo `platform_logs` explícitamente configurado como `false`. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_resource_instance" "tracker_disabled_explicitly" { - name = "my-activity-tracker" - service = "activity-tracker" - plan = "lite" - location = "eu-de" - - platform_logs = false # <-- ¡PROBLEMA! - } - ``` -* **Ubicación de la Alerta:** La alerta señalará específicamente a la línea `platform_logs = false` dentro del recurso `ibm_resource_instance`. - -## Recurso Involucrado - -* `ibm_resource_instance` - -## Solución - -Para solucionar los problemas detectados, asegúrate de que exista al menos un recurso `ibm_resource_instance` para el servicio `activity-tracker` y que incluya la siguiente línea: - -```terraform -resource "ibm_resource_instance" "activity_tracker_correct" { - name = "my-activity-tracker" - service = "activity-tracker" - plan = "lite" - location = "eu-de" # Región compatible con eventos globales - - platform_logs = true -} \ No newline at end of file From 4d432de59599f2f2c1d8f166a5303194f6a65e96 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:47 +0100 Subject: [PATCH 153/900] fix(queries): remove undocumented README.md from ibm_block_storage_customer_encryption_unified --- .../README.md | 58 ------------------- 1 file changed, 58 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/README.md diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/README.md b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/README.md deleted file mode 100644 index bd44b061a45..00000000000 --- a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# Regla KICS: IBM Block Storage Encryption (CMK/BYOK/KYOK) Manual - -## Descripción General - -Esta regla unificada (INFO) audita los volúmenes de almacenamiento en bloque (`ibm_is_volume`) en IBM Cloud VPC para asegurar que utilizan estrategias de cifrado gestionadas por el cliente. - -Cubre tres controles de seguridad distintos pero técnicamente equivalentes en la configuración de Terraform: -1. **CMK (Customer Managed Key):** Uso de claves raíz almacenadas en Key Protect estándar. -2. **BYOK (Bring Your Own Key):** Uso de material de clave generado por el cliente e importado a IBM Cloud. -3. **KYOK (Keep Your Own Key):** Uso de Hyper Protect Crypto Services (HSM dedicado con certificación FIPS 140-2 Nivel 4). - -La presencia del argumento `encryption_key` es el requisito técnico indispensable para habilitar cualquiera de estos tres modelos de control de claves sobre el almacenamiento. - -## Lógica de la Regla - -La política realiza las siguientes comprobaciones: -1. Identifica todos los recursos de tipo `ibm_is_volume`. -2. Verifica si el atributo `encryption_key` está ausente en la definición del recurso. -3. Si falta, genera una alerta informativa indicando que el volumen está utilizando el cifrado por defecto (claves gestionadas por IBM), lo cual puede no satisfacer requisitos de cumplimiento de alto nivel. - -## Casos de Fallo Detectados - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso 1: Cifrado por Defecto (Provider-Managed) - -* **Descripción:** El volumen de bloque ha sido definido sin asignar una clave de cifrado específica. Aunque los datos están cifrados en reposo, las claves son controladas automáticamente por IBM Cloud. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_is_volume" "example_default_enc" { - name = "my-volume" - profile = "10iops-tier" - zone = "us-south-1" - - # Falta el atributo 'encryption_key' - } - ``` -* **Ubicación de la Alerta:** La alerta señalará directamente al bloque del recurso `ibm_is_volume`. - -## Recurso Involucrado - -* `ibm_is_volume` - -## Solución - -Para cumplir con políticas de CMK, BYOK o KYOK, debes asignar el CRN (Cloud Resource Name) de una clave raíz válida proveniente de Key Protect o Hyper Protect Crypto Services. - -```terraform -resource "ibm_is_volume" "secure_volume" { - name = "data-volume" - profile = "general-purpose" - zone = "us-south-1" - - # Habilitar Cifrado por el Cliente (Cubre CMK, BYOK y KYOK) - encryption_key = "crn:v1:bluemix:public:kms:us-south:a/aaaaaa:bbbbbb:key:cccccc" -} \ No newline at end of file From 1884a87b93e4e5726074811196056e0f460c43f8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:49 +0100 Subject: [PATCH 154/900] fix(queries): remove undocumented README.md from ibm_certificate_manager_auto_renew_disabled --- .../README.md | 65 ------------------- 1 file changed, 65 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/README.md diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/README.md b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/README.md deleted file mode 100644 index 8c432427f2c..00000000000 --- a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# Regla KICS: Renovación Automática Habilitada para Certificados - -## Descripción General - -Esta regla de KICS para Terraform asegura que todos los certificados gestionados a través de IBM Cloud Certificate Manager (`ibm_cm_certificate`) tengan habilitada la funcionalidad de renovación automática. - -La gestión manual de la caducidad de los certificados TLS es propensa a errores humanos, que pueden resultar en la caducidad de un certificado y causar interrupciones de servicio, errores de confianza y riesgos de seguridad. La renovación automática es una práctica recomendada para garantizar la continuidad del servicio y reducir la carga operativa de mantenimiento de seguridad. - -## Lógica de la Regla - -La política se compone de dos reglas especializadas para cubrir los casos en los que la renovación automática no está habilitada: -1. **Atributo Faltante:** Identifica recursos donde no se define `auto_renew_enabled`, heredando el valor por defecto inseguro (`false`). -2. **Valor Incorrecto:** Identifica recursos donde se ha desactivado explícitamente la renovación automática. - -## Casos de Fallo Detectados - -A continuación se describen los dos escenarios que esta política detectará. - ---- - -### Caso 1: Atributo `auto_renew_enabled` Ausente - -* **Descripción:** Esta regla detecta cualquier recurso `ibm_cm_certificate` donde el atributo `auto_renew_enabled` no está definido. Según la documentación del proveedor de Terraform para IBM, el valor por defecto de este atributo es `false`. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_cm_certificate" "cert_renew_missing" { - instance_id = ibm_resource_instance.cm_instance.guid - name = "my-cert-renew-missing" - - # El atributo 'auto_renew_enabled' no está presente. - } - ``` -* **Ubicación de la Alerta:** La alerta señalará directamente al bloque de código del recurso `ibm_cm_certificate` al que le falta el atributo. - ---- - -### Caso 2: Atributo `auto_renew_enabled` es `false` - -* **Descripción:** Esta regla busca un recurso `ibm_cm_certificate` que tiene el atributo `auto_renew_enabled` explícitamente configurado como `false`. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_cm_certificate" "cert_renew_disabled" { - instance_id = ibm_resource_instance.cm_instance.guid - name = "my-cert-renew-disabled" - - auto_renew_enabled = false # <-- ¡PROBLEMA! - } - ``` -* **Ubicación de la Alerta:** La alerta señalará específicamente a la línea `auto_renew_enabled = false` dentro del recurso `ibm_cm_certificate`. - -## Recurso Involucrado - -* `ibm_cm_certificate` - -## Solución - -Para solucionar los problemas detectados por esta regla, asegúrate de que cada recurso `ibm_cm_certificate` incluya el atributo habilitado: - -```terraform -resource "ibm_cm_certificate" "cert_correct" { - instance_id = ibm_resource_instance.cm_instance.guid - name = "my-secure-certificate" - - auto_renew_enabled = true -} \ No newline at end of file From fa5180032c67198e14c70e789f9d8fb80cdc6cf6 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:50 +0100 Subject: [PATCH 155/900] fix(queries): remove undocumented README.md from ibm_cis_dns_not_proxied_manual --- .../ibm_cis_dns_not_proxied_manual/README.md | 77 ------------------- 1 file changed, 77 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/README.md diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/README.md b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/README.md deleted file mode 100644 index 0aca177091f..00000000000 --- a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# Regla KICS: IBM CIS DNS Record Not Proxied (Manual) - -## Descripción General - -Esta regla informativa (INFO) audita los registros DNS creados en **IBM Cloud Internet Services (CIS)** mediante el recurso `ibm_cis_dns_record`. - -En la arquitectura de CIS, la **Protección DDoS** de capa 3/4 y capa 7, el WAF y la aceleración CDN solo se activan cuando el tráfico es enrutado a través de la red perimetral de CIS. Esto se configura estableciendo el atributo `proxied` en `true` (modo comúnmente conocido como "Orange Cloud"). - -Si `proxied` es `false` (o se omite), CIS actúa solo como un servidor DNS tradicional ("DNS Only" o "Grey Cloud"), resolviendo la IP del servidor de origen directamente hacia el cliente. Esto expone la IP real del servidor a internet, haciéndolo vulnerable a ataques directos de denegación de servicio (DDoS) y eludiendo cualquier regla de seguridad perimetral de CIS. - -## Lógica de la Regla - -1. Identifica recursos de tipo `ibm_cis_dns_record`. -2. Verifica el valor del atributo `proxied`. -3. Si el valor es explícitamente `false` o si el atributo no ha sido definido (lo que resulta en un valor por defecto de `false`), genera una alerta informativa. - -**Nota para el Auditor:** No todos los registros deben estar protegidos por proxy. Registros TXT, MX, o servicios que utilizan protocolos no soportados por el proxy de CIS (como el tráfico no HTTP en ciertos puertos) deben permanecer en `false`. La alerta sirve para verificar manualmente que los registros `A`, `AAAA` y `CNAME` de aplicaciones web críticas estén bajo el escudo de protección. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Proxy Desactivado Explícitamente - -* **Descripción:** Se ha configurado `proxied = false`. El tráfico fluye directamente al servidor de origen sin pasar por los filtros de CIS. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_cis_dns_record" "dns_only" { - cis_id = ibm_cis.instance.id - domain_id = ibm_cis_domain.example.id - name = "web" - type = "A" - content = "1.2.3.4" - proxied = false # <-- Alerta INFO - } - ``` -* **Ubicación de la Alerta:** Atributo `proxied`. - ---- - -### Caso 2: Proxy No Definido (DNS Only por Defecto) - -* **Descripción:** Falta el atributo en la definición. Por defecto, CIS no activa el proxy, dejando el registro sin protección DDoS. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_cis_dns_record" "default_record" { - cis_id = ibm_cis.instance.id - domain_id = ibm_cis_domain.example.id - name = "app" - type = "A" - content = "1.2.3.4" - # Falta el atributo 'proxied' - } - ``` -* **Ubicación de la Alerta:** Bloque del recurso `ibm_cis_dns_record`. - -## Recurso Involucrado - -* `ibm_cis_dns_record` - -## Solución - -Habilita el proxy para activar la protección DDoS y las características de aceleración de CIS. - -```terraform -resource "ibm_cis_dns_record" "secure_record" { - cis_id = var.cis_instance_id - domain_id = var.domain_id - name = "www" - type = "A" - content = "1.2.3.4" - - # Habilitar protección DDoS, WAF y CDN - proxied = true -} \ No newline at end of file From 30cb0212ec9c2dcb4ecb7fcbd886bec68c3bb96f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:51 +0100 Subject: [PATCH 156/900] fix(queries): remove undocumented README.md from ibm_cis_waf_enabled_manual --- .../ibm/ibm_cis_waf_enabled_manual/README.md | 72 ------------------- 1 file changed, 72 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/README.md diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/README.md b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/README.md deleted file mode 100644 index fd9eb45b2fc..00000000000 --- a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# Regla KICS: IBM CIS WAF Not Enabled (Manual) - -## Descripción General - -Esta regla informativa (INFO) audita la configuración de **IBM Cloud Internet Services (CIS)** para asegurar que la protección de capa de aplicación esté activa. - -El recurso `ibm_cis_domain_settings` permite gestionar las capacidades de seguridad a nivel de dominio. El atributo `waf` funciona como el interruptor principal del Cortafuegos de Aplicaciones Web. Para mitigar riesgos asociados a vulnerabilidades web comunes y cumplir con estándares de seguridad industrial (como PCI-DSS), este atributo debe estar establecido explícitamente en `on`. - -**Nota importante:** Activar `waf = "on"` habilita el motor de inspección, pero la efectividad real depende de la configuración posterior de los paquetes de reglas (OWASP, reglas específicas de CIS, etc.) mediante el recurso `ibm_cis_waf_package`. Esta alerta sirve como punto de partida para verificar que la base de la protección está presente. - -## Lógica de la Regla - -1. Identifica todos los recursos de tipo `ibm_cis_domain_settings`. -2. Verifica la presencia y el valor del atributo `waf`. -3. Genera una alerta informativa si: - * El atributo `waf` está configurado con un valor distinto a `"on"` (por ejemplo, `"off"`). - * El atributo `waf` no ha sido definido en el recurso. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: WAF Deshabilitado Explícitamente - -* **Descripción:** El recurso define el WAF como `"off"`, desactivando la inspección de tráfico de capa 7. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_cis_domain_settings" "insecure" { - cis_id = ibm_cis.instance.id - domain_id = ibm_cis_domain.example.id - waf = "off" # <-- Alerta INFO - } - ``` -* **Ubicación de la Alerta:** Atributo `waf`. - ---- - -### Caso 2: Configuración de WAF Ausente - -* **Descripción:** No se especifica el estado del WAF, lo que puede llevar a estados de seguridad inconsistentes dependiendo del plan de CIS contratado. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_cis_domain_settings" "default_settings" { - cis_id = ibm_cis.instance.id - domain_id = ibm_cis_domain.example.id - # El atributo 'waf' no está definido - } - ``` -* **Ubicación de la Alerta:** Bloque del recurso `ibm_cis_domain_settings`. - -## Recurso Involucrado - -* `ibm_cis_domain_settings` - -## Solución - -Habilita el motor del WAF estableciendo el atributo a `"on"` dentro de la configuración del dominio. - -```terraform -resource "ibm_cis_domain_settings" "secure_settings" { - cis_id = ibm_cis.instance.id - domain_id = ibm_cis_domain.example.id - - # Habilitar WAF Global - waf = "on" - - # Recomendaciones adicionales de seguridad - ssl = "strict" - min_tls_version = "1.2" -} \ No newline at end of file From b06247f3da5a22cc3aa8da491b6d3fc26f79a623 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:53 +0100 Subject: [PATCH 157/900] fix(queries): remove undocumented README.md from ibm_cloudant_cmk_encryption_manual --- .../README.md | 75 ------------------- 1 file changed, 75 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/README.md diff --git a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/README.md b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/README.md deleted file mode 100644 index c15aa384c73..00000000000 --- a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/README.md +++ /dev/null @@ -1,75 +0,0 @@ -# Regla KICS: IBM Cloudant Encryption with CMK (Manual) - -## Descripción General - -Esta regla informativa (INFO) audita las instancias de **IBM Cloudant** desplegadas mediante el recurso genérico `ibm_resource_instance` para verificar el uso de claves gestionadas por el cliente. - -Cloudant cifra los datos en reposo por defecto utilizando claves gestionadas por IBM. Sin embargo, para cumplir con requisitos de gestión de claves avanzada como **CMK** (Customer Managed Key) o **BYOK** (Bring Your Own Key), se debe inyectar el CRN (Cloud Resource Name) de una clave raíz proveniente de Key Protect o Hyper Protect Crypto Services. - -En Terraform, esta configuración se realiza pasando el parámetro específico `key_protect_key` dentro del mapa de `parameters` del recurso. Si este mapa se omite o si la clave no está presente dentro de él, la instancia se provisionará con el cifrado estándar del proveedor. - -## Lógica de la Regla - -La política realiza las siguientes comprobaciones sobre recursos `ibm_resource_instance` donde el servicio es `"cloudantnosqldb"`: -1. **Ausencia de Parámetros:** Detecta si el bloque `parameters` no ha sido definido en absoluto. -2. **Parámetro Faltante:** Detecta si el bloque `parameters` existe pero no incluye la entrada `key_protect_key`. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Bloque de Parámetros Ausente - -* **Descripción:** No se define ninguna configuración adicional, por lo que se asume el cifrado por defecto de IBM. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_resource_instance" "cloudant_no_params" { - name = "my-nosql-db" - service = "cloudantnosqldb" - plan = "standard" - location = "us-south" - # Falta el bloque parameters - } - ``` -* **Ubicación de la Alerta:** Nivel del recurso `ibm_resource_instance`. - ---- - -### Caso 2: Clave de Cifrado Faltante en Parámetros - -* **Descripción:** Se definen parámetros pero se omite la clave de seguridad `key_protect_key`. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_resource_instance" "cloudant_partial_params" { - name = "my-nosql-db" - service = "cloudantnosqldb" - plan = "standard" - location = "us-south" - parameters = { - "db_type" = "nosql" - } - } - ``` -* **Ubicación de la Alerta:** Atributo `parameters`. - -## Recurso Involucrado - -* `ibm_resource_instance` (Service: `cloudantnosqldb`) - -## Solución - -Añade el bloque `parameters` con la clave `key_protect_key` apuntando a un CRN válido. - -```terraform -resource "ibm_resource_instance" "cloudant_secure" { - name = "my-secure-cloudant" - service = "cloudantnosqldb" - plan = "standard" - location = "us-south" - - parameters = { - key_protect_key = "crn:v1:bluemix:public:kms:us-south:a/aaaa:bbbb:key:cccc" - } -} \ No newline at end of file From e6e39ff0ee49ffcbe1d5cd0046e78aa068acb7d1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:54 +0100 Subject: [PATCH 158/900] fix(queries): remove undocumented README.md from ibm_container_cluster_entitlement_check --- .../README.md | 62 ------------------- 1 file changed, 62 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/README.md diff --git a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/README.md b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/README.md deleted file mode 100644 index a8aad50d427..00000000000 --- a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# Regla KICS: IBM Cluster Entitlement Key Missing (Automated) - -## Descripción General - -Esta regla informativa (INFO) audita el recurso `ibm_container_cluster` en IBM Cloud Kubernetes Service (IKS). - -En IBM Cloud, la gestión de **Image Pull Secrets** (credenciales para descargar imágenes de contenedores) se puede automatizar en Terraform de varias formas. Una de las más directas y seguras para el software empresarial es el uso del argumento `entitlement`. - -Cuando se define este argumento, el sistema crea automáticamente un secreto de Kubernetes dentro del clúster con las credenciales necesarias para autenticarse contra el **IBM Entitled Registry**. Esto asegura la integridad de la cadena de suministro al permitir el despliegue de **IBM Cloud Paks** y otro software licenciado sin la necesidad de crear, inyectar o gestionar manualmente objetos `Secret` de Kubernetes, reduciendo el riesgo de exposición de credenciales y fallos en el despliegue por secretos expirados. - -## Lógica de la Regla - -1. Identifica recursos de tipo `ibm_container_cluster`. -2. Verifica si el atributo `entitlement` está presente en la configuración. -3. Si falta, genera una alerta informativa. - -**Nota técnica:** No todos los clústeres requieren software titulado (muchos corren aplicaciones propias). Sin embargo, en entornos corporativos de IBM, es una mejor práctica verificar si se ha habilitado esta automatización. Para registros privados que no sean el Entitled Registry, se recomienda usar el recurso `ibm_container_bind_service`. - -## Casos de Fallo Detectados - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso 1: Clave de Titulación (Entitlement) Faltante - -* **Descripción:** El clúster se provisiona sin credenciales automáticas para el registro de IBM. Esto requerirá que el administrador gestione los secretos de descarga de imágenes de forma manual. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_container_cluster" "example_no_entitlement" { - name = "my-app-cluster" - datacenter = "dal10" - machine_type = "b3c.4x16" - hardware = "shared" - public_vlan_id = "1234567" - private_vlan_id = "7654321" - - # Falta el atributo 'entitlement' - } - ``` -* **Ubicación de la Alerta:** Bloque del recurso `ibm_container_cluster`. - -## Recurso Involucrado - -* `ibm_container_cluster` - -## Solución - -Si el clúster va a ejecutar software licenciado de IBM, añade tu clave de titulación al recurso del clúster. - -```terraform -resource "ibm_container_cluster" "secure_cluster" { - name = "production-cluster" - datacenter = "dal10" - machine_type = "u3c.2x4" - hardware = "shared" - public_vlan_id = "123456" - private_vlan_id = "654321" - - # Automatización del Image Pull Secret para IBM Entitled Registry - entitlement = "cloud_pak_entitlement_key_or_api_key" -} \ No newline at end of file From 2f36eec43dfc5491cd46c3e1bc8c893d924cecca Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:55 +0100 Subject: [PATCH 159/900] fix(queries): remove undocumented README.md from ibm_container_registry_va_alerts_missing --- .../README.md | 54 ------------------- 1 file changed, 54 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/README.md diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/README.md b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/README.md deleted file mode 100644 index 4472f3e9caf..00000000000 --- a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# Regla KICS: IBM Cluster Missing VA Alerts (Automated) - -## Descripción General - -Esta regla de severidad **MEDIA** audita el despliegue de clústeres de Kubernetes (`ibm_container_cluster`) en IBM Cloud para asegurar que existan canales de comunicación activos para la gestión de vulnerabilidades. - -El uso de orquestadores de contenedores implica el manejo constante de imágenes de software. IBM Cloud proporciona el **Vulnerability Advisor (VA)**, que escanea automáticamente estas imágenes en el registro. Sin embargo, en un flujo de trabajo de DevSecOps eficiente, el escaneo por sí solo no es suficiente; es imperativo que el sistema pueda notificar a los responsables cuando se detecten nuevas vulnerabilidades o cambios en el estado de seguridad de una imagen. - -Si estás desplegando un clúster mediante Terraform, la práctica recomendada es incluir en el mismo código la configuración de las notificaciones (`ibm_container_va_notification`), ya sea mediante correo electrónico o webhooks, para garantizar una respuesta rápida ante posibles amenazas. - -## Lógica de la Regla - -1. Identifica todos los recursos de tipo `ibm_container_cluster` en la configuración. -2. Escanea el documento de Terraform en busca de *cualquier* instancia del recurso `ibm_container_va_notification`. -3. Si se detecta la creación de un clúster pero no existe ninguna configuración de notificaciones de VA, genera una alerta apuntando al recurso del clúster. - -## Casos de Fallo Detectados - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso 1: Clúster sin Alertas de Vulnerabilidad - -* **Descripción:** Se define un clúster de Kubernetes en la infraestructura, pero se omite la configuración del canal de alertas (email/webhook) para el Vulnerability Advisor. Esto crea un punto ciego donde las imágenes vulnerables podrían pasar desapercibidas. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_container_cluster" "production_cluster" { - name = "prod-cluster" - datacenter = "dal10" - machine_type = "b3c.4x16" - hardware = "shared" - public_vlan_id = "123456" - private_vlan_id = "654321" - - # No hay un recurso 'ibm_container_va_notification' asociado en el proyecto - } - ``` -* **Ubicación de la Alerta:** Bloque del recurso `ibm_container_cluster`. - -## Recurso Involucrado - -* `ibm_container_cluster` -* `ibm_container_va_notification` - -## Solución - -Para solucionar esta alerta, añade un recurso de notificación de VA que apunte al clúster o al grupo de recursos correspondiente. - -```terraform -resource "ibm_container_va_notification" "vulnerability_alerts" { - cluster_id = ibm_container_cluster.production_cluster.id - email = "security-ops@tu-empresa.com" -} \ No newline at end of file From c778af483a289cf19868423cd7136c56d46f7586 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:57 +0100 Subject: [PATCH 160/900] fix(queries): remove undocumented README.md from ibm_cos_bucket_customer_encryption_unified --- .../README.md | 60 ------------------- 1 file changed, 60 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/README.md diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/README.md b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/README.md deleted file mode 100644 index 1635ba2a4fd..00000000000 --- a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# Regla KICS: IBM COS Bucket Encryption (CMK/BYOK/KYOK) Manual - -## Descripción General - -Esta regla unificada (INFO) verifica si los buckets de **IBM Cloud Object Storage (COS)** están configurados para utilizar claves de cifrado gestionadas por el cliente, en lugar de las claves estándar gestionadas por el proveedor. - -En la arquitectura de IBM Cloud, el uso del argumento `key_protect` en el recurso de Terraform es el habilitador técnico para implementar tres niveles avanzados de seguridad: - -1. **CMK (Customer Managed Key):** Utiliza claves raíz almacenadas en el servicio **Key Protect**. -2. **BYOK (Bring Your Own Key):** Permite al cliente importar su propio material de clave generado externamente. -3. **KYOK (Keep Your Own Key):** Ofrece el nivel más alto de aislamiento mediante el uso de **Hyper Protect Crypto Services (HPCS)** con un HSM dedicado con certificación FIPS 140-2 Nivel 4. - -Si este argumento se omite, el bucket utiliza el cifrado en reposo por defecto de IBM (AES-256), donde IBM controla la rotación y el ciclo de vida de la clave. Esta regla sirve para que el auditor verifique si la sensibilidad de los datos almacenados exige un control soberano de las llaves. - -## Lógica de la Regla - -1. Identifica todos los recursos de tipo `ibm_cos_bucket`. -2. Verifica si el atributo `key_protect` está presente en la definición del bucket. -3. Genera una alerta informativa si el atributo no existe, indicando que se está utilizando la configuración de cifrado por defecto. - -## Casos de Fallo Detectados - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso 1: Cifrado Gestionado por el Proveedor (Default) - -* **Descripción:** El bucket de COS ha sido configurado sin especificar una clave de seguridad del cliente. IBM Cloud cifra los datos, pero el cliente no posee el control total sobre la clave raíz. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_cos_bucket" "public_data" { - bucket_name = "my-bucket-standard" - resource_instance_id = ibm_resource_instance.cos_instance.id - storage_class = "smart" - region_location = "us-south" - - # Falta el atributo 'key_protect' - } - ``` -* **Ubicación de la Alerta:** Bloque del recurso `ibm_cos_bucket`. - -## Recurso Involucrado - -* `ibm_cos_bucket` - -## Solución - -Para habilitar CMK, BYOK o KYOK, debes proporcionar el CRN (Cloud Resource Name) de tu clave raíz de Key Protect o Hyper Protect en el atributo `key_protect`. - -```terraform -resource "ibm_cos_bucket" "secure_storage" { - bucket_name = "vault-bucket-secure" - resource_instance_id = ibm_resource_instance.cos_instance.id - storage_class = "smart" - region_location = "us-south" - - # Habilitar Cifrado Gestionado por el Cliente - key_protect = "crn:v1:bluemix:public:kms:us-south:a/aaaa:bbbb:key:cccc" -} \ No newline at end of file From 14e0553225103cd9044567049a54af814bf507d7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:58 +0100 Subject: [PATCH 161/900] fix(queries): remove undocumented README.md from ibm_database_cmk_encryption_manual --- .../README.md | 57 ------------------- 1 file changed, 57 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/README.md diff --git a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/README.md b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/README.md deleted file mode 100644 index d2ed09aeeff..00000000000 --- a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# Regla KICS: IBM Cloud Database Without CMK (Manual) - -## Descripción General - -Esta regla informativa (INFO) audita los recursos `ibm_database` en Terraform para identificar instancias de la familia **IBM Cloud Databases (ICD)** que no utilizan claves de cifrado gestionadas por el cliente. - -Este recurso se utiliza para aprovisionar una amplia variedad de servicios de datos gestionados, incluyendo PostgreSQL, Redis, Elasticsearch, MongoDB, etcd, entre otros. Por defecto, todas estas bases de datos cifran el almacenamiento en reposo utilizando claves gestionadas automáticamente por IBM Cloud. - -Sin embargo, para cumplir con marcos regulatorios estrictos o políticas internas de seguridad avanzadas (**CMK**, **BYOK** o **KYOK**), es imperativo que el cliente proporcione y gestione la clave raíz. Esto se logra asignando el CRN (Cloud Resource Name) de una clave proveniente de **Key Protect** o **Hyper Protect Crypto Services (HPCS)** en el argumento `key_protect_key`. - -## Lógica de la Regla - -La política realiza las siguientes acciones: -1. Identifica todos los recursos de tipo `ibm_database` en el código de Terraform. -2. Verifica si el atributo `key_protect_key` ha sido definido. -3. Si el atributo falta, genera una alerta informativa indicando que la instancia depende del cifrado por defecto del proveedor. - -## Casos de Fallo Detectados - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso 1: Cifrado por Defecto (Provider-Managed) - -* **Descripción:** La base de datos ICD ha sido configurada sin asignar una clave de seguridad propia. Aunque los datos están cifrados, el cliente no tiene control sobre el ciclo de vida de la clave de cifrado de volumen. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_database" "postgres_default" { - name = "my-db-standard" - service = "databases-for-postgresql" - plan = "standard" - location = "us-south" - - # Falta el atributo 'key_protect_key' - } - ``` -* **Ubicación de la Alerta:** Bloque del recurso `ibm_database`. - -## Recurso Involucrado - -* `ibm_database` - -## Solución - -Para habilitar el cifrado gestionado por el cliente, asigna el CRN de una clave raíz válida de tu Vault (Key Protect o HPCS) al argumento `key_protect_key`. - -```terraform -resource "ibm_database" "secure_db" { - name = "my-secure-postgres" - service = "databases-for-postgresql" - plan = "standard" - location = "us-south" - - # Habilitar CMK/BYOK/KYOK - key_protect_key = "crn:v1:bluemix:public:kms:us-south:a/aaaa:bbbb:key:cccc" -} \ No newline at end of file From 01e51b9d5ae7775975896a4029e9addf0fd8cbca Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:16:59 +0100 Subject: [PATCH 162/900] fix(queries): remove undocumented README.md from ibm_iam_account_ip_restrictions_manual --- .../README.md | 69 ------------------- 1 file changed, 69 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/README.md diff --git a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/README.md b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/README.md deleted file mode 100644 index 2aa835fe523..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# Regla KICS: IBM Account IP Restrictions (Manual) - -## Descripción General - -Esta regla informativa (INFO) audita la configuración global de la cuenta en IBM Cloud a través del recurso `ibm_iam_account_settings`. - -Para mitigar el riesgo de compromiso de credenciales y accesos no autorizados, es una práctica de seguridad fundamental restringir el acceso a la consola de IBM Cloud y a las interfaces de API únicamente a direcciones IP o rangos de red de confianza (como la VPN corporativa, oficinas centrales o gateways de seguridad). - -Si el atributo `allowed_ip_addresses` no se configura, IBM Cloud permite por defecto el acceso desde cualquier dirección IP pública (0.0.0.0/0). Habilitar estas restricciones reduce drásticamente la superficie de ataque para amenazas externas, ya que incluso si un atacante obtiene credenciales válidas, el sistema denegará la conexión si no se origina desde un origen autorizado. - -## Lógica de la Regla - -La política realiza las siguientes validaciones: -1. Identifica el recurso único `ibm_iam_account_settings` en el proyecto. -2. **Validación de Presencia:** Verifica si el atributo `allowed_ip_addresses` ha sido definido. -3. **Validación de Integridad:** Verifica que la lista proporcionada no sea una lista vacía `[]`. -4. Genera una alerta informativa si falta la configuración, instando al auditor a definir el perímetro de red de la cuenta. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Acceso Irrestricto (Sin Atributo) - -* **Descripción:** El recurso no define ninguna restricción de red. El acceso a la cuenta está abierto a cualquier punto de internet. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_iam_account_settings" "default" { - mfa = "TOTP" - session_expiration_in_seconds = 3600 - # Falta el atributo 'allowed_ip_addresses' - } - ``` -* **Ubicación de la Alerta:** Bloque del recurso `ibm_iam_account_settings`. - ---- - -### Caso 2: Lista de IPs Vacía - -* **Descripción:** Se define el atributo pero no se incluyen direcciones IP de confianza. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_iam_account_settings" "empty_list" { - allowed_ip_addresses = [] # <-- Alerta INFO - } - ``` -* **Ubicación de la Alerta:** Atributo `allowed_ip_addresses`. - -## Recurso Involucrado - -* `ibm_iam_account_settings` - -## Solución - -Define explícitamente la lista de direcciones IP o subredes (en formato CIDR) que deben tener permiso de acceso a la cuenta. - -```terraform -resource "ibm_iam_account_settings" "secure_account" { - mfa = "TOTP" - session_expiration_in_seconds = 86400 - - # Restringir acceso solo a la VPN corporativa y oficina central - allowed_ip_addresses = [ - "203.0.113.10", # IP Estática Oficina - "192.0.2.0/24" # Rango VPN Corporativa - ] -} \ No newline at end of file From 4786a6451c7ae6b31146c18e72a472bbb8f63e0c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:00 +0100 Subject: [PATCH 163/900] fix(queries): remove undocumented README.md from ibm_iam_account_mfa_disabled --- .../ibm_iam_account_mfa_disabled/README.md | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/README.md diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/README.md b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/README.md deleted file mode 100644 index 0531e8afc6f..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Regla KICS: MFA Obligatorio a Nivel de Cuenta en IBM IAM - -## Descripción General - -Esta regla de KICS para Terraform asegura que la Autenticación Multi-Factor (MFA) esté habilitada y forzada a un nivel seguro para toda la cuenta de IBM Cloud. La configuración se gestiona a través del recurso `ibm_iam_account_settings`. - -Forzar el uso de MFA es una de las medidas de seguridad más efectivas para proteger una cuenta contra el acceso no autorizado. Incluso si las credenciales (usuario y contraseña) de un administrador o usuario con privilegios son comprometidas, el MFA actúa como una barrera crítica de segundo nivel. - -## Lógica de la Regla - -La política se divide en tres comprobaciones complementarias para cubrir todos los escenarios de riesgo: -1. **Ausencia de Recurso:** Verifica que exista el recurso de configuración de cuenta. -2. **Atributo Faltante:** Verifica que el parámetro `mfa` esté definido explícitamente. -3. **Nivel Inseguro:** Asegura que no se utilicen niveles débiles. Los niveles seguros aceptados son `LEVEL2` (TOTP/App de autenticación) y `LEVEL3` (U2F/Llave física). - -## Casos de Fallo Detectados - -A continuación se describen los tres escenarios que esta política detectará. - ---- - -### Caso 1: Recurso `ibm_iam_account_settings` Ausente -* **Descripción:** No se está gestionando la política de la cuenta mediante código, dejando el MFA bajo configuración manual o por defecto (inseguro). -* **Ubicación:** Bloque `provider "ibm"`. - -### Caso 2: Atributo `mfa` Ausente -* **Descripción:** El recurso de configuración existe pero no define el comportamiento del MFA. -* **Ubicación:** Recurso `ibm_iam_account_settings`. - -### Caso 3: Valor de `mfa` Inseguro (`NONE` o `LEVEL1`) -* **Descripción:** El MFA está desactivado (`NONE`) o utiliza métodos débiles como email (`LEVEL1`). -* **Ubicación:** Atributo `mfa`. - -## Recurso Involucrado - -* `ibm_iam_account_settings` - -## Solución - -Para cumplir con esta política, define el recurso de configuración de cuenta y fuerza el uso de MFA de nivel 2 o superior. - -```terraform -resource "ibm_iam_account_settings" "secure_iam_policy" { - # Forzar el uso de TOTP (Time-based One-Time Password) - mfa = "LEVEL2" -} \ No newline at end of file From 5d6701aa6d82d49b5a22f15d2a044d6cedf195fb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:02 +0100 Subject: [PATCH 164/900] fix(queries): remove undocumented README.md from ibm_iam_api_key_unused_manual --- .../ibm_iam_api_key_unused_manual/README.md | 60 ------------------- 1 file changed, 60 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/README.md diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/README.md b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/README.md deleted file mode 100644 index 77a3fa2022b..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# Regla KICS: IBM Cloud API Keys Unused for 180 Days (Manual) - -## Descripción General - -Esta regla informativa (INFO) audita la creación de claves de API en **IBM Cloud**, cubriendo tanto las claves asociadas a usuarios (`ibm_iam_api_key`) como las asociadas a identidades de servicio o Service IDs (`ibm_iam_service_api_key`). - -El cumplimiento de normativas de seguridad de la industria y las mejores prácticas de IBM Cloud exigen que las credenciales de acceso que no se hayan utilizado durante un periodo prolongado (típicamente 180 días) sean desactivadas o eliminadas para minimizar el riesgo de uso indebido. - -**Terraform no tiene visibilidad sobre el historial de uso en tiempo real** ni sobre la telemetría de autenticación de las claves que gestiona. Por lo tanto, esta regla actúa como un recordatorio crítico para que el equipo de seguridad implemente procesos de monitoreo externos (como scripts de auditoría con la CLI de IBM Cloud o integraciones con el Activity Tracker) que detecten y reaccionen ante claves inactivas. - -## Lógica de la Regla - -La política realiza las siguientes acciones: -1. Identifica la creación de cualquier recurso `ibm_iam_api_key`. -2. Identifica la creación de cualquier recurso `ibm_iam_service_api_key`. -3. Genera una alerta informativa para cada clave detectada, instando al auditor a verificar que existe una política de ciclo de vida activa. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: API Key de Usuario Creada - -* **Descripción:** Se ha definido una clave de API personal. Estas claves suelen tener privilegios amplios y deben ser vigiladas. -* **Ejemplo de Código Terraform:** - ```terraform - resource "ibm_iam_api_key" "my_key" { - name = "user-api-key" - } - ``` -* **Ubicación de la Alerta:** Recurso `ibm_iam_api_key`. - ---- - -### Caso 2: API Key de Service ID Creada - -* **Descripción:** Se ha definido una clave para una aplicación o servicio automatizado. -* **Ejemplo de Código Terraform:** - ```terraform - resource "ibm_iam_service_api_key" "service_key" { - name = "app-service-key" - service_id_crn = ibm_iam_service_id.serviceID.crn - } - ``` -* **Ubicación de la Alerta:** Recurso `ibm_iam_service_api_key`. - -## Recursos Involucrados - -* `ibm_iam_api_key` -* `ibm_iam_service_api_key` - -## Solución - -Establezca un proceso automatizado o una revisión periódica (fuera de Terraform) que consulte el estado de las claves. Puede usar la CLI de IBM Cloud para identificar claves inactivas: - -```bash -# Ejemplo: Listar claves de API y verificar el campo 'Last Used' -ibmcloud iam api-keys --output json \ No newline at end of file From ef92257696ada2138ed2c914284c678688e97794 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:03 +0100 Subject: [PATCH 165/900] fix(queries): remove undocumented README.md from ibm_iam_owner_api_key_manual --- .../ibm_iam_owner_api_key_manual/README.md | 50 ------------------- 1 file changed, 50 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/README.md diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/README.md b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/README.md deleted file mode 100644 index fa1c74979f2..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Regla KICS: IBM Owner Account API Key (Manual) - -## Descripción General - -Esta regla informativa (INFO) detecta la creación de claves de API de usuario (`ibm_iam_api_key`) en IBM Cloud para mitigar riesgos de privilegios excesivos. - -Según las mejores prácticas de seguridad, como el **IBM Cloud Foundations Benchmark**, la cuenta propietaria (**Account Owner**) no debe tener claves de API activas. El propietario tiene privilegios absolutos sobre la facturación, gestión de identidades y la eliminación total de la cuenta. Las claves de API eluden el control de MFA (Autenticación Multi-Factor), por lo que una clave de propietario comprometida otorga control total e irreversible a un atacante. - -## Lógica de la Regla - -1. Identifica recursos del tipo `ibm_iam_api_key`. -2. Genera una alerta informativa que requiere validación manual. Dado que Terraform no tiene visibilidad del rol del usuario (Owner o no) en tiempo de escaneo estático, la regla alerta sobre cualquier clave de usuario creada. -3. Esta regla **excluye** las claves de Service ID (`ibm_iam_service_api_key`), ya que estas son la alternativa segura recomendada y no pueden poseer el rol de "Account Owner". - -## Casos de Fallo Detectados - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso 1: API Key de Usuario (Potencial Owner) - -* **Descripción:** Se ha creado una clave de API personal. Se debe confirmar que el usuario que emite la clave no sea el propietario de la cuenta. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_iam_api_key" "personal_key" { - name = "admin-key" - } - ``` -* **Ubicación de la Alerta:** Recurso `ibm_iam_api_key`. - -## Recurso Involucrado - -* `ibm_iam_api_key` - -## Solución - -1. Verifique en la consola de IAM que el usuario asociado a la clave no es el "Account Owner". -2. Si lo es, elimine la clave y utilice un **Service ID** con permisos limitados mediante el principio de mínimo privilegio. - -```terraform -# RECOMENDADO: Usar Service ID para automatizaciones -resource "ibm_iam_service_id" "app_identity" { - name = "app-automation-id" -} - -resource "ibm_iam_service_api_key" "app_key" { - name = "automation-key" - iam_service_id = ibm_iam_service_id.app_identity.iam_id -} \ No newline at end of file From bdaf6af2984ad024b9e20e1888968b8c96b93ff3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:04 +0100 Subject: [PATCH 166/900] fix(queries): remove undocumented README.md from ibm_iam_policy_assigned_to_user_manual --- .../README.md | 65 ------------------- 1 file changed, 65 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/README.md diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/README.md b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/README.md deleted file mode 100644 index 844fcfb4414..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# Regla KICS: IBM IAM Policies Attached to Users (Manual) - -## Descripción General - -Esta regla informativa (INFO) detecta el uso del recurso `ibm_iam_user_policy` en Terraform. - -La asignación de permisos basada en grupos (**RBAC**) es el pilar de una gobernanza de identidades robusta. Las mejores prácticas de IBM Cloud y marcos de cumplimiento como CIS recomiendan gestionar los permisos a través de **Grupos de Acceso** (Access Groups) en lugar de asignar políticas directamente a usuarios individuales. - -La asignación directa usuario a usuario crea una infraestructura "snowflake" donde cada identidad tiene permisos únicos, lo que hace casi imposible auditar el impacto de cambios globales o garantizar el principio de mínimo privilegio. El uso de grupos facilita el "onboarding" y "offboarding" de usuarios y centraliza el control de acceso. - -## Lógica de la Regla - -1. Escanea el código de Terraform en busca del recurso `ibm_iam_user_policy`. -2. Genera una alerta para cada ocurrencia detectada. -3. El auditor debe verificar si esta asignación directa está realmente justificada (como en el caso de cuentas de administración de emergencia o "break-glass") o si debe ser refactorizada para integrarse en un grupo de acceso. - -## Casos de Fallo Detectados - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso 1: Asignación de Política Directa a Usuario - -* **Descripción:** Se utiliza el recurso `ibm_iam_user_policy` para otorgar roles a una identidad de usuario específica. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_iam_user_policy" "direct_access" { - ibm_id = "user@example.com" - roles = ["Administrator"] - - resources { - service = "is" - } - } - ``` -* **Ubicación de la Alerta:** Recurso `ibm_iam_user_policy`. - -## Recurso Involucrado - -* `ibm_iam_user_policy` - -## Solución - -La práctica recomendada consiste en crear un grupo de acceso, asignar la política a dicho grupo y posteriormente añadir a los usuarios como miembros. - -```terraform -# PATRÓN CORRECTO Y ESCALABLE -resource "ibm_iam_access_group" "admins" { - name = "Cloud-Administrators" -} - -resource "ibm_iam_access_group_policy" "admin_policy" { - access_group_id = ibm_iam_access_group.admins.id - roles = ["Administrator"] - - resources { - service = "is" - } -} - -resource "ibm_iam_access_group_members" "admin_members" { - access_group_id = ibm_iam_access_group.admins.id - ibm_ids = ["user@example.com"] -} \ No newline at end of file From 3090819d5225cbf09caeef8c7b4783386c106e7a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:05 +0100 Subject: [PATCH 167/900] fix(queries): remove undocumented README.md from ibm_iam_restrict_apikey_creation_manual --- .../README.md | 50 ------------------- 1 file changed, 50 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/README.md diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/README.md b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/README.md deleted file mode 100644 index 7f68b7b9667..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Regla KICS: Restrict API Key & Service ID Creation (Manual) - -## Descripción General - -Esta regla informativa (INFO) audita las asignaciones de roles en **IBM Cloud IAM** para asegurar que la capacidad de crear identidades y credenciales esté estrictamente controlada. - -Según los controles de seguridad **CIS IBM Cloud Foundations**, la creación de **claves de API de usuario** y **Service IDs** es una acción de alto privilegio que debe restringirse a un número mínimo de usuarios de confianza. En IBM Cloud, roles predefinidos de plataforma como `Administrator` o `Editor` sobre el servicio de identidad incluyen permisos potentes como `iam.service_id.create` o `iam.api_key.create`. - -Esta regla identifica las definiciones de políticas para que un auditor verifique que estos roles no se estén asignando de forma masiva o a sujetos que no requieren capacidades administrativas de identidad, cumpliendo con el **Principio de Mínimo Privilegio**. - -## Lógica de la Regla - -La política realiza las siguientes acciones: -1. Identifica recursos `ibm_iam_user_policy` y `ibm_iam_access_group_policy`. -2. Extrae y evalúa la lista de roles asignados en cada política. -3. Genera una alerta para que se verifique manualmente si los roles asignados (especialmente Administrator o Editor) son estrictamente necesarios para el propósito del usuario o grupo. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Revisión de Roles en Políticas de Usuario -* **Descripción:** Se asignan roles directamente a una identidad de usuario. -* **Ubicación de la Alerta:** Atributo `roles` dentro de `ibm_iam_user_policy`. - -### Caso 2: Revisión de Roles en Políticas de Grupo -* **Descripción:** Se asignan roles a un Grupo de Acceso (Access Group), afectando a todos sus miembros. -* **Ubicación de la Alerta:** Atributo `roles` dentro de `ibm_iam_access_group_policy`. - -## Recurso Involucrado - -* `ibm_iam_user_policy` -* `ibm_iam_access_group_policy` - -## Solución - -Revisa los roles asignados. Evita otorgar roles de plataforma amplios como `Editor` o `Administrator` de forma generalizada. Si un usuario solo necesita gestionar recursos existentes, utiliza el rol `Operator` o `Viewer`. Si se requiere una granularidad mayor, implemente **Roles Personalizados (Custom Roles)** que omitan específicamente las acciones de creación de identidades. - -```terraform -# Ejemplo de política restrictiva usando roles de menor privilegio -resource "ibm_iam_access_group_policy" "restricted_group_policy" { - access_group_id = ibm_iam_access_group.group.id - roles = ["Viewer", "Operator"] # Roles que no permiten creación de IDs/Keys - - resources { - service = "is" # VPC Infrastructure - } -} \ No newline at end of file From 74e4f71a43cd86da57f77c15099394398c090ab4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:06 +0100 Subject: [PATCH 168/900] fix(queries): remove undocumented README.md from ibm_iam_session_expiration_too_long --- .../README.md | 56 ------------------- 1 file changed, 56 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/README.md diff --git a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/README.md b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/README.md deleted file mode 100644 index fc8fc907db3..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# Regla KICS: IBM Account Session Expiration Too Long - -## Descripción General - -Esta regla de severidad **MEDIA** verifica que la **Expiración de Sesión** en la configuración de la cuenta de IBM Cloud esté configurada de manera segura para mitigar riesgos de seguridad de identidad. - -Por defecto, o si se configura de forma laxa, las sesiones de usuario pueden permanecer activas durante periodos prolongados (hasta 24 horas). Esto aumenta considerablemente la ventana de oportunidad para ataques de secuestro de sesión (Session Hijacking) y accesos no autorizados en terminales físicas compartidas. Según las mejores prácticas de la industria y el **CIS IBM Cloud Foundations Benchmark**, se recomienda limitar la duración de la sesión a **3600 segundos (1 hora)** o menos para forzar una re-autenticación periódica. - -## Lógica de la Regla - -La política audita el recurso `ibm_iam_account_settings` realizando dos comprobaciones: -1. **Validación de Presencia:** Si falta el atributo `session_expiration_in_seconds`, la regla falla al asumir que la cuenta depende de valores por defecto inseguros. -2. **Validación de Valor:** Si el valor configurado es numéricamente superior a `3600` segundos, la regla falla. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Configuración de Expiración Ausente -* **Descripción:** El recurso existe pero no define el tiempo de vida de la sesión, delegando el control al proveedor. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_iam_account_settings" "insecure_default" { - mfa = "LEVEL2" - # Falta session_expiration_in_seconds - } - ``` -* **Ubicación de la Alerta:** Bloque del recurso `ibm_iam_account_settings`. - ---- - -### Caso 2: Tiempo de Sesión Excesivo -* **Descripción:** La sesión se ha configurado con una duración mayor a la hora recomendada (ej. 8 horas o 24 horas). -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_iam_account_settings" "too_long" { - session_expiration_in_seconds = 28800 # 8 horas - } - ``` -* **Ubicación de la Alerta:** Atributo `session_expiration_in_seconds`. - -## Recurso Involucrado - -* `ibm_iam_account_settings` - -## Solución - -Asegúrese de definir el límite de sesión en 3600 segundos o menos para cumplir con los estándares de seguridad. - -```terraform -resource "ibm_iam_account_settings" "compliant_settings" { - mfa = "LEVEL2" - session_expiration_in_seconds = 3600 # 1 Hora -} \ No newline at end of file From 7a0f1ecb6e86b2c75a3b6fe7a3e8eddcfe56db83 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:08 +0100 Subject: [PATCH 169/900] fix(queries): remove undocumented README.md from ibm_iks_cluster_logging_disabled --- .../README.md | 55 ------------------- 1 file changed, 55 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/README.md diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/README.md b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/README.md deleted file mode 100644 index c47c34a27be..00000000000 --- a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Regla KICS: Logging Habilitado para Clusters de IKS - -## Descripción General - -Esta regla de KICS para Terraform asegura que cada clúster de IBM Cloud Kubernetes Service (`ibm_container_cluster`) tenga una configuración de logging de IBM Cloud Log Analysis (`ibm_ob_logging_config`) correctamente asociada. - -La agregación de logs de un clúster de Kubernetes es una práctica fundamental para la observabilidad y la seguridad. Permite a los equipos de desarrollo y operaciones centralizar los logs de los contenedores, los nodos y los componentes del sistema. Sin esta configuración, el análisis forense tras un incidente de seguridad o la resolución de errores en aplicaciones distribuidas se vuelve extremadamente compleja. - -## Lógica de la Regla - -La política implementa una lógica de correlación de recursos en todo el proyecto. Su función es identificar cualquier instancia de `ibm_container_cluster` que no esté referenciada en el atributo `scope` de ningún recurso `ibm_ob_logging_config`. La conexión se considera válida cuando el nombre o CRN del clúster aparece en el alcance (scope) de la configuración de observabilidad. - -## Casos de Fallo Detectados - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso Único: Configuración de Logging Ausente para un Clúster - -* **Descripción:** Esta regla detecta cualquier clúster de IKS que se esté aprovisionando sin su correspondiente pieza de telemetría para logs. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_container_cluster" "orphan_cluster" { - name = "my-production-cluster" - datacenter = "dal10" - machine_type = "b3c.4x16" - hardware = "shared" - # No existe un recurso ibm_ob_logging_config que use este clúster como scope - } - ``` -* **Ubicación de la Alerta:** La alerta señalará directamente al bloque de código del recurso `ibm_container_cluster` huérfano de configuración de logs. - -## Recursos Involucrados - -* `ibm_container_cluster` -* `ibm_ob_logging_config` - -## Solución - -Para solucionar los problemas detectados, asegúrese de que para cada clúster exista un recurso `ibm_ob_logging_config` que vincule el clúster con una instancia de Log Analysis. - -```terraform -resource "ibm_ob_logging_config" "cluster_telemetry" { - # Vincular con el clúster mediante su CRN o ID - scope = ibm_container_cluster.my_cluster.crn - instance = ibm_resource_instance.log_analysis_inst.guid -} - -resource "ibm_resource_instance" "log_analysis_inst" { - name = "log-aggregator" - service = "logdna" - plan = "7-day" - location = "us-south" -} \ No newline at end of file From 47a52cc65f351ff3f70e7fd4b186d4e15aca3932 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:09 +0100 Subject: [PATCH 170/900] fix(queries): remove undocumented README.md from ibm_iks_cluster_monitoring_disabled --- .../README.md | 55 ------------------- 1 file changed, 55 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/README.md diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/README.md b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/README.md deleted file mode 100644 index c3ff1801860..00000000000 --- a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Regla KICS: Monitorización Habilitada para Clusters de IKS - -## Descripción General - -Esta regla de KICS para Terraform asegura que cada clúster de IBM Cloud Kubernetes Service (`ibm_container_cluster`) tenga una configuración de monitorización de **IBM Cloud Monitoring** (`ibm_ob_monitoring_config`) vinculada. - -La monitorización de un clúster de Kubernetes es un requisito crítico para la operatividad y estabilidad. Permite obtener métricas en tiempo real sobre el uso de CPU, memoria, tráfico de red y latencia de los servicios. Sin esta visibilidad, los equipos de operaciones no pueden detectar cuellos de botella, prever la saturación de recursos mediante escalado automático, ni responder proactivamente a incidentes de salud en la infraestructura. - -## Lógica de la Regla - -La política implementa una lógica de correlación cruzada en el documento de Terraform. Identifica cualquier recurso `ibm_container_cluster` que no sea referenciado en el atributo `scope` de ningún recurso `ibm_ob_monitoring_config`. La vinculación se valida cuando el nombre o el CRN del clúster se incluye en el ámbito de la configuración de monitorización. - -## Casos de Fallo Detectados - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso Único: Configuración de Monitorización Ausente para un Clúster - -* **Descripción:** El clúster se aprovisiona sin los agentes o la vinculación necesaria para enviar métricas al servicio de monitorización centralizado de IBM Cloud. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_container_cluster" "cluster_unmonitored" { - name = "production-iks-cluster" - datacenter = "dal10" - machine_type = "b3c.4x16" - hardware = "shared" - # No existe un recurso ibm_ob_monitoring_config apuntando a este clúster - } - ``` -* **Ubicación de la Alerta:** La alerta señalará directamente al bloque de código del recurso `ibm_container_cluster` huérfano de monitorización. - -## Recursos Involucrados - -* `ibm_container_cluster` -* `ibm_ob_monitoring_config` - -## Solución - -Para solucionar esta alerta, debe existir un recurso `ibm_ob_monitoring_config` que conecte el clúster con una instancia de monitorización (basada en Sysdig). - -```terraform -resource "ibm_ob_monitoring_config" "monitoring_setup" { - # Relación directa con el clúster - scope = ibm_container_cluster.my_cluster.crn - instance = ibm_resource_instance.sysdig_instance.guid -} - -resource "ibm_resource_instance" "sysdig_instance" { - name = "cluster-metrics-aggregator" - service = "sysdig-monitor" - plan = "graduated-tier" - location = "us-south" -} \ No newline at end of file From 01dca84dc9b7e90c38f69762efcc7aad71ab4dc5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:10 +0100 Subject: [PATCH 171/900] fix(queries): remove undocumented README.md from ibm_instance_os_disk_encryption_manual --- .../README.md | 51 ------------------- 1 file changed, 51 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/README.md diff --git a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/README.md b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/README.md deleted file mode 100644 index b0f3d5b5695..00000000000 --- a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# Regla KICS: IBM Instance OS Disk Encryption (Manual) - -## Descripción General - -Esta regla informativa (INFO) audita las instancias de servidor virtual (**VSI**) de la infraestructura VPC (`ibm_is_instance`) para verificar que el cifrado del disco de arranque esté bajo el control del cliente. - -Por defecto, IBM Cloud cifra el volumen de arranque (boot volume) de cada instancia utilizando claves gestionadas por el proveedor. Sin embargo, para cumplir con estándares de seguridad avanzados como **FIPS 140-2**, o normativas financieras y gubernamentales, se requiere el uso de **Customer Managed Keys (CMK)** o **Keep Your Own Key (KYOK)**. - -Al proporcionar el CRN de una clave de **Key Protect** o **Hyper Protect Crypto Services** en la configuración de la instancia, el cliente obtiene la capacidad de revocar el acceso a los datos del sistema operativo de forma instantánea. - -## Lógica de la Regla - -La política evalúa el recurso `ibm_is_instance` bajo dos escenarios: -1. **Ausencia de Configuración de Volumen:** Si el bloque `boot_volume` no está presente, la instancia se crea con parámetros por defecto (cifrado gestionado por IBM). -2. **Ausencia de Clave de Cifrado:** Si el bloque `boot_volume` existe pero el parámetro `encryption` no está definido, se considera que el volumen no está utilizando claves gestionadas por el cliente. - -## Casos de Fallo Detectados - -A continuación se describen los escenarios que esta política detectará. - ---- - -### Caso 1: Cifrado por Defecto (Bloque Ausente) -* **Descripción:** No se define configuración de disco de arranque, delegando el cifrado a IBM Cloud. -* **Ubicación de la Alerta:** Bloque del recurso `ibm_is_instance`. - -### Caso 2: Cifrado por Defecto (Atributo Ausente) -* **Descripción:** Se configura el volumen de arranque pero se omite la clave de cifrado. -* **Ubicación de la Alerta:** Atributo `boot_volume`. - -## Recurso Involucrado - -* `ibm_is_instance` - -## Solución - -Defina el bloque `boot_volume` e incluya el CRN de su clave raíz de Key Protect en el argumento `encryption`. - -```terraform -resource "ibm_is_instance" "secure_vsi" { - name = "secure-production-server" - image = "r006-723f851b-4043-42e5-9467-33a39e802375" - profile = "bx2-2x8" - - boot_volume { - name = "os-disk-secure" - encryption = "crn:v1:bluemix:public:kms:us-south:a/aaaa:bbbb:key:cccc" - } - - # ... otros parámetros de red y vpc ... -} \ No newline at end of file From 7f305082445ee40b230dcc392c1950d0b56150e2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:11 +0100 Subject: [PATCH 172/900] fix(queries): remove undocumented README.md from ibm_kms_key_rotation_disabled --- .../ibm_kms_key_rotation_disabled/README.md | 63 ------------------- 1 file changed, 63 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/README.md diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/README.md b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/README.md deleted file mode 100644 index 743a0644829..00000000000 --- a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# Regla KICS: Rotación Automática de Claves en IBM Key Protect - -## Descripción General - -Esta regla de KICS para Terraform asegura que todas las claves gestionadas por el cliente (`ibm_kms_key`) en **IBM Key Protect** tengan una política de rotación automática habilitada y configurada correctamente. - -La rotación periódica de claves criptográficas es una práctica de seguridad fundamental que responde al principio de **Criptografía Ágil**. El objetivo principal es limitar el "radio de explosión" (blast radius): al rotar la clave periódicamente, se reduce drásticamente la cantidad de datos que podrían ser descifrados en el hipotético caso de que el material de una clave específica se viera comprometido. Además, forzar rotaciones regulares garantiza que los procesos operativos sean capaces de manejar el ciclo de vida de las claves sin depender de una única clave estática de duración indefinida. - -## Lógica de la Regla - -La política audita el recurso `ibm_kms_key` cubriendo tres escenarios de riesgo: -1. **Ausencia de Bloque:** Detecta si no se ha definido el bloque `rotation_policy`. -2. **Atributo Faltante:** Detecta si el bloque existe pero omite el intervalo de tiempo. -3. **Valor Inválido/Cero:** Detecta si el intervalo se ha configurado en `0`, lo cual desactiva funcionalmente la rotación. - -## Casos de Fallo Detectados - -A continuación se describen los tres escenarios que esta política detectará. - ---- - -### Caso 1: Bloque `rotation_policy` Ausente -* **Descripción:** El recurso de clave existe pero no contiene ninguna instrucción de rotación automática. -* **Ejemplo de Código Terraform:** - ```terraform - resource "ibm_kms_key" "key_static" { - instance_id = "instance-id" - key_name = "static-key" - standard_key = false - } - ``` -* **Ubicación de la Alerta:** Bloque del recurso `ibm_kms_key`. - ---- - -### Caso 2: Atributo `rotation_interval_month` Ausente -* **Descripción:** Se define la política pero no se especifica cada cuántos meses debe ocurrir la rotación. -* **Ubicación de la Alerta:** Bloque `rotation_policy`. - ---- - -### Caso 3: Intervalo de Rotación en Cero -* **Descripción:** El intervalo está configurado en `0`, lo que inhabilita la automatización del ciclo de vida. -* **Ubicación de la Alerta:** Atributo `rotation_interval_month`. - -## Recurso Involucrado - -* `ibm_kms_key` - -## Solución - -Defina un bloque `rotation_policy` con un intervalo válido de entre 1 y 12 meses. - -```terraform -resource "ibm_kms_key" "key_compliant" { - instance_id = ibm_resource_instance.kms_instance.guid - key_name = "secure-rotating-key" - standard_key = false - - rotation_policy { - rotation_interval_month = 6 # Rota cada semestre - } -} \ No newline at end of file From 237ebcb8654363ba81c0b42ddf1537c55dbee6cb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:13 +0100 Subject: [PATCH 173/900] fix(queries): remove undocumented README.md from ibm_logdna_archiving_disabled --- .../ibm_logdna_archiving_disabled/README.md | 53 ------------------- 1 file changed, 53 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/README.md diff --git a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/README.md b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/README.md deleted file mode 100644 index 8d1ae843581..00000000000 --- a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# Regla KICS: Archivado Habilitado para IBM LogDNA - -## Descripción General - -Esta regla de KICS para Terraform asegura que cada instancia de **IBM LogDNA** (`ibm_logdna_instance`) tenga el archivado de eventos configurado mediante el recurso `ibm_logdna_archive`. - -La retención de logs a largo plazo es una exigencia crítica en marcos de cumplimiento como **PCI DSS**, **SOC 2**, o **HIPAA**. El archivado permite mover los registros de la capa de búsqueda activa a una capa de almacenamiento de bajo costo (IBM Cloud Object Storage), garantizando que los datos estén disponibles para auditorías o investigaciones forenses meses o años después de su generación, incluso si la instancia operativa de Log Analysis ha purgado los datos de su caché de búsqueda. - -## Lógica de la Regla - -La política realiza un escaneo de correlación cruzada en el proyecto de Terraform. Identifica cualquier recurso `ibm_logdna_instance` que no sea referenciado en el atributo `instance_id` de ningún recurso `ibm_logdna_archive`. El fallo se dispara ante la **omisión completa** del recurso de archivado, lo que implica un riesgo de pérdida definitiva de datos tras el periodo de retención del plan. - -## Casos de Fallo Detectados - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso Único: Recurso `ibm_logdna_archive` Ausente - -* **Descripción:** Se provisiona una instancia de logs para gestionar la actividad de la plataforma o aplicaciones, pero no se define un destino de persistencia para el archivado. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_logdna_instance" "my_logs" { - name = "prod-logs" - plan = "7-day" - target_resource_instance_id = ibm_resource_instance.logdna_inst.id - } - - # ERROR: Falta el recurso ibm_logdna_archive que apunte a 'my_logs' - ``` -* **Ubicación de la Alerta:** Bloque del recurso `ibm_logdna_instance` huérfano de archivado. - -## Recursos Involucrados - -* `ibm_logdna_instance` -* `ibm_logdna_archive` - -## Solución - -Asegúrese de vincular cada instancia de LogDNA con un recurso `ibm_logdna_archive` que apunte a un bucket de IBM Cloud Object Storage. - -```terraform -resource "ibm_logdna_archive" "archive_setup" { - instance_id = ibm_logdna_instance.my_logs.id - - cos { - api_key = var.ibmcloud_api_key - bucket = "my-archiving-bucket" - endpoint = "s3.private.us-south.cloud-object-storage.appdomain.cloud" - instance_crn = ibm_resource_instance.cos_inst.id - } -} \ No newline at end of file From 80967559ab471449c75b4c2fb71b2e8d5e8e53be Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:14 +0100 Subject: [PATCH 174/900] fix(queries): remove undocumented README.md from ibm_logdna_view_without_alert --- .../ibm_logdna_view_without_alert/README.md | 51 ------------------- 1 file changed, 51 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_logdna_view_without_alert/README.md diff --git a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/README.md b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/README.md deleted file mode 100644 index 0277252afde..00000000000 --- a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# Regla KICS: Alertas Definidas para Vistas de IBM LogDNA - -## Descripción General - -Esta regla de severidad **BAJA** de KICS para Terraform asegura que cada vista personalizada de **IBM Log Analysis (LogDNA)** (`ibm_logdna_view`) tenga al menos una alerta (`ibm_logdna_alert`) configurada. - -Las vistas personalizadas se diseñan para filtrar y aislar eventos críticos, como errores de sistema, intentos de acceso fallidos o picos de tráfico. Sin embargo, la monitorización solo es efectiva si es proactiva. Si una vista existe pero carece de una alerta vinculada, el equipo de operaciones o seguridad depende de la revisión manual periódica de los logs, lo que aumenta drásticamente el tiempo de respuesta ante incidentes (MTTR). - -## Lógica de la Regla - -La política realiza una correlación cruzada dentro de los archivos de Terraform. Identifica cualquier recurso `ibm_logdna_view` cuyo nombre no sea referenciado en el atributo `view` de ningún recurso `ibm_logdna_alert`. La regla se activa ante la **omisión del recurso de alerta**, señalando que la vista no tiene un canal de notificación activo. - -## Casos de Fallo Detectados - -A continuación se describe el escenario que esta política detectará. - ---- - -### Caso Único: Vista de LogDNA sin Alerta Asociada - -* **Descripción:** Se define una vista específica para errores críticos o auditoría, pero no se inyecta un recurso de alerta para notificar a los responsables. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "ibm_logdna_view" "security_audit_view" { - name = "Security-Audit-Trail" - query = "app:iam-service action:login-failed" - # Error: No hay un recurso ibm_logdna_alert asociado a esta vista - } - ``` -* **Ubicación de la Alerta:** Bloque del recurso `ibm_logdna_view` huérfano de notificación. - -## Recursos Involucrados - -* `ibm_logdna_view` -* `ibm_logdna_alert` - -## Solución - -Asocie un recurso `ibm_logdna_alert` a la vista utilizando el nombre de la misma en el parámetro `view`. - -```terraform -resource "ibm_logdna_alert" "security_alert" { - name = "IAM-Failure-Alert" - view = ibm_logdna_view.security_audit_view.name - - notification_channel { - email { - recipients = ["security-ops@tu-empresa.com"] - } - } -} \ No newline at end of file From 2c327bc6dd094fb4229dcc2c9de5be2af2d655b3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:15 +0100 Subject: [PATCH 175/900] fix(queries): remove undocumented README.md from oci_cloud_guard_problem_event_rule_missing --- .../README.md | 95 ------------------- 1 file changed, 95 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/README.md diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/README.md deleted file mode 100644 index 7c3926dad45..00000000000 --- a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/README.md +++ /dev/null @@ -1,95 +0,0 @@ -# Regla KICS: Notificación para Problemas Detectados por Cloud Guard en OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para generar notificaciones cuando OCI Cloud Guard detecta un nuevo "problema". - -Habilitar Cloud Guard es solo el primer paso; su efectividad real depende de la capacidad del equipo de seguridad para responder a sus hallazgos. Si los problemas que Cloud Guard detecta no generan notificaciones automáticas, las alertas críticas pueden pasar desapercibidas durante un tiempo considerable, retrasando la mitigación de riesgos y aumentando la exposición. - -## Lógica de la Regla - -La política implementa una búsqueda **global** en todo el proyecto Terraform (analizando todos los archivos `.tf` simultáneamente). - -Inspecciona todos los recursos `oci_events_rule` definidos en la infraestructura para verificar si **al menos uno** de ellos cumple las siguientes condiciones: -1. Está habilitado (`is_enabled = true`). -2. Su condición de filtrado incluye el tipo de evento específico: `com.oraclecloud.cloudguard.problem`. - -Si no se encuentra ninguna regla que cumpla ambos requisitos en todo el proyecto, se genera una alerta. - -## Caso de Fallo Detectado - -A continuación se describe el escenario que esta política detectará. - ---- -### Caso Único: Regla de Eventos para Problemas de Cloud Guard Ausente o Mal Configurada - -* **Descripción:** Esta regla se activa si en toda la configuración del proyecto no se encuentra ningún recurso `oci_events_rule` habilitado que capture el evento de Cloud Guard. Esto incluye casos donde la regla no existe, o existe pero monitoriza eventos diferentes. -* **Ubicación de la Alerta:** La alerta se anclará al bloque `provider "oci" {}`, indicando que falta una configuración global de seguridad. - -* **Ejemplo de Código Terraform Problemático:** - ```terraform - # El proyecto puede tener otras reglas de eventos, pero ninguna para - # notificar los problemas detectados por Cloud Guard. - - resource "oci_events_rule" "example_rule_wrong_event" { - display_name = "rule-for-instance-events" - compartment_id = var.compartment_id - is_enabled = true - - # FALLO: Esta condición monitoriza el lanzamiento de instancias, - # pero ignora los problemas de seguridad de Cloud Guard. - condition = "{\"eventType\":[\"com.oraclecloud.compute.instance.launch.end\"]}" - - actions { - actions { - action_type = "ONS" - topic_id = oci_ons_notification_topic.test_topic.id - } - } - } - ``` - -## Recurso Involucrado - -* `oci_events_rule` - -## Solución - -Para solucionar el problema detectado, asegúrate de que tu configuración de Terraform incluya al menos un recurso `oci_events_rule` habilitado y configurado específicamente para el evento de problema de Cloud Guard. - -Se recomienda filtrar por niveles de riesgo (CRITICAL, HIGH) para evitar ruido, como se muestra a continuación: - -```terraform -# RECURSO REQUERIDO PARA LA SOLUCIÓN -resource "oci_events_rule" "cloud_guard_problem_rule" { - display_name = "notify-on-cloud-guard-problems" - description = "Sends a notification when Cloud Guard detects a new problem" - compartment_id = var.tenancy_ocid - is_enabled = true - - # La condición busca el evento específico y filtra por severidad. - condition = jsonencode({ - eventType = [ - "com.oraclecloud.cloudguard.problem" - ], - data = { - "riskLevel" = [ - "CRITICAL", - "HIGH" - ] - } - }) - - actions { - actions { - action_type = "ONS" - topic_id = oci_ons_notification_topic.security_alerts_topic.id - } - } -} - -# Recurso auxiliar: Tópico de notificación para enviar la alerta. -resource "oci_ons_notification_topic" "security_alerts_topic" { - compartment_id = var.compartment_id - name = "security-alerts-topic" -} \ No newline at end of file From 38da84ed5aaf6a40e025f8229db1f058768c759c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:16 +0100 Subject: [PATCH 176/900] fix(queries): remove undocumented README.md from oci_cloud_guard_root_compartment_disabled --- .../README.md | 76 ------------------- 1 file changed, 76 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/README.md diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/README.md b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/README.md deleted file mode 100644 index b9a7f33354c..00000000000 --- a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# Regla KICS: Cloud Guard Habilitado en el Compartimento Raíz de OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que el servicio OCI Cloud Guard esté habilitado (`status = "ENABLED"`) y configurado para operar a nivel del compartimento raíz (*tenancy*). - -Cloud Guard es el servicio de gestión de la postura de seguridad (CSPM) nativo de OCI. Proporciona una visión centralizada de la seguridad, detecta configuraciones incorrectas y actividades anómalas, y puede automatizar la respuesta a problemas. Para obtener la máxima visibilidad y protección, IBM y Oracle recomiendan activarlo en el compartimento raíz, ya que sus políticas se heredan a todos los compartimentos hijos. - -## Lógica de la Regla - -La política se divide en tres reglas para cubrir todos los escenarios de mala configuración: -1. El recurso `oci_cloud_guard_configuration` no existe. -2. El recurso existe, pero su `status` no es `ENABLED`. -3. El recurso existe y está habilitado, pero no está asignado al compartimento raíz. - -## Casos de Fallo Detectados - -A continuación se describen los tres escenarios que esta política detectará. - ---- -### Caso 1: Recurso `oci_cloud_guard_configuration` Ausente - -* **Descripción:** Esta regla se activa si no existe ningún recurso `oci_cloud_guard_configuration` en toda la configuración, lo que significa que Cloud Guard no está siendo gestionado por Terraform. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - # El proyecto no define ninguna configuración para Cloud Guard. - ``` -* **Ubicación de la Alerta:** La alerta se anclará al bloque `provider "oci" {}`. - ---- -### Caso 2: `status` de Cloud Guard no es `ENABLED` - -* **Descripción:** Esta regla detecta un recurso `oci_cloud_guard_configuration` que existe, pero cuyo `status` es diferente de `"ENABLED"` (por ejemplo, `"DISABLED"`). -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "oci_cloud_guard_configuration" "cg_config_disabled" { - compartment_id = var.tenancy_ocid - reporting_region = "us-ashburn-1" - status = "DISABLED" # <-- ¡PROBLEMA! - } - ``` -* **Ubicación de la Alerta:** La alerta señalará directamente a la línea `status = "DISABLED"`. - ---- -### Caso 3: Cloud Guard no está en el Compartimento Raíz - -* **Descripción:** Esta regla detecta un recurso `oci_cloud_guard_configuration` que está habilitado (`status = "ENABLED"`), pero su `compartment_id` no es el del *tenancy* (raíz). La regla identifica esto de forma heurística, comprobando que el OCID del compartimento no contenga la palabra `tenancy`. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "oci_cloud_guard_configuration" "cg_config_wrong_compartment" { - # Apunta a un compartimento hijo en lugar del raíz. - compartment_id = var.child_compartment_ocid # <-- ¡PROBLEMA! - - reporting_region = "us-ashburn-1" - status = "ENABLED" - } - ``` -* **Ubicación de la Alerta:** La alerta señalará directamente a la línea `compartment_id`. - -## Recurso Involucrado - -* `oci_cloud_guard_configuration` - -## Solución - -Para solucionar los problemas detectados, asegúrate de que exista un único recurso `oci_cloud_guard_configuration` con el `status` en `"ENABLED"` y el `compartment_id` apuntando al OCID del *tenancy* (compartimento raíz). - -```terraform -resource "oci_cloud_guard_configuration" "cg_config_correct" { - # El compartment_id debe ser el del tenancy para una cobertura completa. - compartment_id = var.tenancy_ocid - - reporting_region = "us-ashburn-1" - status = "ENABLED" -} -``` \ No newline at end of file From 083b84ebf637c1f6928e1b2b0f0b38a64b68a81d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:17 +0100 Subject: [PATCH 177/900] fix(queries): remove undocumented README.md from oci_compute_legacy_metadata_enabled --- .../README.md | 71 ------------------- 1 file changed, 71 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/README.md diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/README.md b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/README.md deleted file mode 100644 index 1755079010f..00000000000 --- a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# Regla KICS: Endpoints de Metadatos Legacy Deshabilitados en Instancias de OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que todas las instancias de cómputo de OCI (`oci_core_instance`) tengan los endpoints del servicio de metadatos legacy (IMDSv1) deshabilitados. - -El servicio de metadatos de instancia (IMDS) permite a una instancia obtener información sobre sí misma. La versión 1 (legacy) es vulnerable a ataques de tipo SSRF (Server-Side Request Forgery). La versión 2 (IMDSv2) introduce protecciones que mitigan este riesgo. Deshabilitar los endpoints legacy y forzar el uso de IMDSv2 es una práctica de seguridad fundamental para proteger las instancias. - -## Lógica de la Regla - -La política verifica la presencia y configuración del atributo `are_legacy_imds_endpoints_disabled` dentro del bloque `agent_config`. - -## Casos de Fallo Detectados - -A continuación se describen los tres escenarios que esta política detectará. - ---- -### Caso 1: Bloque `agent_config` Ausente - -* **Descripción:** El recurso `oci_core_instance` no define el bloque `agent_config`. Por defecto, esto implica que la configuración de seguridad no está aplicada. -* **Ejemplo:** - ```terraform - resource "oci_core_instance" "test" { - # Falta el bloque agent_config - } - ``` -* **Ubicación de la Alerta:** Bloque del recurso `oci_core_instance`. - ---- -### Caso 2: Atributo Ausente en `agent_config` - -* **Descripción:** El bloque `agent_config` existe, pero no contiene el atributo `are_legacy_imds_endpoints_disabled`. El valor por defecto es `false` (inseguro). -* **Ejemplo:** - ```terraform - resource "oci_core_instance" "test" { - agent_config { - # Falta el atributo are_legacy_imds_endpoints_disabled - is_monitoring_disabled = false - } - } - ``` -* **Ubicación de la Alerta:** Bloque `agent_config`. - ---- -### Caso 3: Atributo Configurado como `false` - -* **Descripción:** El atributo `are_legacy_imds_endpoints_disabled` está presente pero explícitamente configurado como `false`, habilitando los endpoints legacy inseguros. -* **Ejemplo:** - ```terraform - resource "oci_core_instance" "test" { - agent_config { - are_legacy_imds_endpoints_disabled = false # <-- ¡PROBLEMA! - } - } - ``` -* **Ubicación de la Alerta:** Línea del atributo `are_legacy_imds_endpoints_disabled`. - -## Recurso Involucrado - -* `oci_core_instance` - -## Solución - -```terraform -resource "oci_core_instance" "test_instance_correct" { - # ... otros atributos ... - - agent_config { - are_legacy_imds_endpoints_disabled = true - } -} \ No newline at end of file From d960e8bb8ebc95ae09a3f1982c52b0d3ddf7edf8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:18 +0100 Subject: [PATCH 178/900] fix(queries): remove undocumented README.md from oci_compute_secure_boot_disabled --- .../README.md | 73 ------------------- 1 file changed, 73 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_compute_secure_boot_disabled/README.md diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/README.md b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/README.md deleted file mode 100644 index 5ed4f78d123..00000000000 --- a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# Regla KICS: Secure Boot Habilitado en Instancias de Cómputo de OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que todas las instancias de cómputo de OCI (`oci_core_instance`) que lo soporten tengan la funcionalidad de "Arranque Seguro" (Secure Boot) habilitada. - -Secure Boot es un estándar de seguridad desarrollado por la industria para asegurar que un dispositivo arranque utilizando únicamente software de confianza del fabricante del equipo original (OEM). Cuando el PC arranca, el firmware comprueba la firma de cada pieza de software de arranque, incluido el sistema operativo. Si las firmas son válidas, el PC arranca y el firmware cede el control al sistema operativo. Habilitarlo protege contra malware a nivel de arranque como los rootkits. - -## Lógica de la Regla - -La política verifica la presencia y configuración del atributo `is_secure_boot_enabled` dentro del bloque `shape_config`. - -## Casos de Fallo Detectados - -A continuación se describen los tres escenarios que esta política detectará. - ---- -### Caso 1: Bloque `shape_config` Ausente - -* **Descripción:** El recurso `oci_core_instance` no define el bloque `shape_config`. Por defecto, esto implica que Secure Boot está deshabilitado. -* **Ejemplo:** - ```terraform - resource "oci_core_instance" "test" { - # Falta el bloque shape_config - } - ``` -* **Ubicación de la Alerta:** Bloque del recurso `oci_core_instance`. - ---- -### Caso 2: Atributo Ausente en `shape_config` - -* **Descripción:** El bloque `shape_config` existe, pero no contiene el atributo `is_secure_boot_enabled`. El valor por defecto es `false`. -* **Ejemplo:** - ```terraform - resource "oci_core_instance" "test" { - shape_config { - # Falta is_secure_boot_enabled - ocpus = 1 - } - } - ``` -* **Ubicación de la Alerta:** Bloque `shape_config`. - ---- -### Caso 3: Atributo Configurado como `false` - -* **Descripción:** El atributo `is_secure_boot_enabled` está presente pero explícitamente configurado como `false`. -* **Ejemplo:** - ```terraform - resource "oci_core_instance" "test" { - shape_config { - is_secure_boot_enabled = false # <-- ¡PROBLEMA! - } - } - ``` -* **Ubicación de la Alerta:** Línea del atributo `is_secure_boot_enabled`. - -## Recurso Involucrado - -* `oci_core_instance` - -## Solución - -Para solucionar los problemas detectados, asegúrate de que cada recurso `oci_core_instance` incluya un bloque `shape_config` con el atributo `is_secure_boot_enabled` configurado en `true`. - -```terraform -resource "oci_core_instance" "test_instance_correct" { - # ... otros atributos ... - - shape_config { - is_secure_boot_enabled = true - } -} \ No newline at end of file From 0dac157d69e9c8d689088d7ef7dc25bae6e32381 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:20 +0100 Subject: [PATCH 179/900] fix(queries): remove undocumented README.md from oci_default_tags_not_defined --- .../oci_default_tags_not_defined/README.md | 69 ------------------- 1 file changed, 69 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_default_tags_not_defined/README.md diff --git a/assets/queries/terraform/oci/oci_default_tags_not_defined/README.md b/assets/queries/terraform/oci/oci_default_tags_not_defined/README.md deleted file mode 100644 index 5d457d791fe..00000000000 --- a/assets/queries/terraform/oci/oci_default_tags_not_defined/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# Regla KICS: Tags por Defecto Definidos en OCI - -## Descripción General - -Esta regla de KICS para Terraform verifica que se haya definido una política de etiquetado por defecto en la configuración de OCI. La gestión de esta política se realiza a través del recurso `oci_identity_tag_default`. - -El uso de tags por defecto es una práctica de gobernanza fundamental en la nube. Permite asegurar que todos los recursos creados dentro de un compartimento específico reciban automáticamente un conjunto predefinido de etiquetas. Esto es esencial para la gestión de costes, la automatización de procesos, el control de acceso y la auditoría. - -## Lógica de la Regla - -La política implementa una única regla para verificar la existencia de al menos un recurso `oci_identity_tag_default` en toda la configuración de Terraform. Si no se encuentra ninguno, se asume que no se está gestionando una política de etiquetado por defecto. - -## Caso de Fallo Detectado - -A continuación se describe el escenario que esta política detectará. - ---- -### Caso Único: Recurso `oci_identity_tag_default` Ausente - -* **Descripción:** Esta regla se activa si en toda la configuración de Terraform no se encuentra ni un solo recurso de tipo `oci_identity_tag_default`. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - # El proyecto contiene varios recursos de OCI, pero ninguno define - # una política de tags por defecto. - - resource "oci_core_vcn" "example_vcn" { - compartment_id = var.compartment_id - # ... - } - ``` -* **Ubicación de la Alerta:** La alerta será general y se anclará al bloque `provider "oci" {}` para indicar que falta un recurso `oci_identity_tag_default` en la configuración global. - -## Recurso Involucrado - -* `oci_identity_tag_default` - -## Solución - -Para solucionar el problema detectado, asegúrate de que tu configuración de Terraform incluya al menos un recurso `oci_identity_tag_default`. Este recurso requiere que primero se defina un `oci_identity_tag_namespace` y un `oci_identity_tag`. - -```terraform -# Es necesario definir un espacio de nombres para los tags. -resource "oci_identity_tag_namespace" "example_ns" { - compartment_id = var.compartment_id - description = "Namespace for default tags" - name = "example-namespace" -} - -# Es necesario definir el tag que se usará por defecto. -resource "oci_identity_tag" "example_tag" { - tag_namespace_id = oci_identity_tag_namespace.example_ns.id - description = "Tag for cost center" - name = "CostCenter" -} - -# RECURSO REQUERIDO PARA LA SOLUCIÓN -resource "oci_identity_tag_default" "example_default_tag" { - compartment_id = var.compartment_id - - # ID del tag que se aplicará por defecto. - tag_definition_id = oci_identity_tag.example_tag.id - - # Valor que se aplicará por defecto. - value = "IT-DEPT-123" - - # Asegura que los usuarios no puedan sobreescribir este valor por defecto. - is_required = true -} -``` \ No newline at end of file From 3646b9f5ea6677fefcef72ae6175a8ba1979f579 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:21 +0100 Subject: [PATCH 180/900] fix(queries): remove undocumented README.md from oci_iam_group_change_event_rule_missing --- .../README.md | 122 ------------------ 1 file changed, 122 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/README.md diff --git a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/README.md deleted file mode 100644 index 76f87609c67..00000000000 --- a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/README.md +++ /dev/null @@ -1,122 +0,0 @@ -# Regla KICS: Notificación para Cambios en Grupos de IAM en OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio (creación, actualización o eliminación) en los grupos de IAM de la cuenta de OCI. - -Los grupos de IAM son la base de la gestión de permisos en OCI. Un atacante o un actor interno malicioso podría crear un nuevo grupo con altos privilegios, añadir usuarios a un grupo de administradores, o eliminar un grupo existente para causar una denegación de servicio. Monitorizar estos cambios en tiempo real es una medida de seguridad esencial para detectar escaladas de privilegios no autorizadas o manipulaciones en los controles de acceso. - -## Lógica de la Regla - -La política realiza un análisis exhaustivo en busca de reglas que capturen los siguientes tres tipos de eventos críticos de IAM: -1. `com.oraclecloud.identity.creategroup` -2. `com.oraclecloud.identity.updategroup` -3. `com.oraclecloud.identity.deletegroup` - -La validación se divide en tres comprobaciones específicas: -1. **Existencia Global:** Verifica si existe al menos una regla en todo el proyecto que monitorice eventos de grupos IAM. -2. **Integridad de la Condición:** Si la regla existe, verifica que incluya **los tres** tipos de eventos mencionados anteriormente. -3. **Estado de la Regla:** Verifica que la regla, si está correctamente configurada, se encuentre habilitada (`is_enabled = true`). - -## Casos de Fallo Detectados - -A continuación se describen los tres escenarios específicos que esta política detectará. - ---- -### Caso 1: Regla de Eventos para Grupos IAM Totalmente Ausente - -* **Descripción:** Esta regla se activa si en toda la configuración de Terraform no se encuentra ningún recurso `oci_events_rule` que haga referencia a eventos de grupos de IAM. Esto indica una falta total de auditoría sobre estos recursos. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - # El proyecto define recursos de infraestructura, pero carece de reglas de - # eventos para seguridad de IAM. - - provider "oci" { - region = "us-ashburn-1" - } - ``` -* **Ubicación de la Alerta:** La alerta será general y se anclará al bloque `provider "oci" {}`. - ---- -### Caso 2: Regla de Eventos Incompleta (Faltan Tipos de Eventos) - -* **Descripción:** Se ha detectado una regla `oci_events_rule` destinada a monitorizar grupos, pero su configuración es incompleta. La propiedad `condition` incluye algunos eventos (por ejemplo, solo la creación), pero omite otros críticos (como la eliminación o actualización). -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "oci_events_rule" "iam_group_partial" { - display_name = "audit-iam-create" - is_enabled = true - - # FALLO: Solo monitoriza la creación, ignorando actualizaciones y borrados. - condition = jsonencode({ - "eventType": ["com.oraclecloud.identity.creategroup"] - }) - - actions { - # ... configuración de acciones ... - } - } - ``` -* **Ubicación de la Alerta:** La alerta señalará específicamente al atributo `condition` dentro del recurso `oci_events_rule` afectado. - ---- -### Caso 3: Regla de Eventos Deshabilitada - -* **Descripción:** Existe una regla `oci_events_rule` correctamente configurada que incluye todos los eventos de grupos de IAM necesarios, pero se encuentra explícitamente deshabilitada (`is_enabled = false`), por lo que no está protegiendo el entorno. -* **Ejemplo de Código Terraform Problemático:** - ```terraform - resource "oci_events_rule" "iam_group_disabled" { - display_name = "audit-iam-all" - - # FALLO: La regla está bien definida pero apagada. - is_enabled = false - - condition = jsonencode({ - "eventType": [ - "com.oraclecloud.identity.creategroup", - "com.oraclecloud.identity.updategroup", - "com.oraclecloud.identity.deletegroup" - ] - }) - } - ``` -* **Ubicación de la Alerta:** La alerta señalará al atributo `is_enabled` dentro del recurso. - -## Recurso Involucrado - -* `oci_events_rule` - -## Solución - -Para solucionar cualquiera de los problemas detectados, asegúrate de configurar un recurso `oci_events_rule` que incluya los tres eventos requeridos y esté habilitado. - -```terraform -# RECURSO REQUERIDO PARA LA SOLUCIÓN -resource "oci_events_rule" "iam_group_change_rule" { - display_name = "audit-rule-for-iam-group-changes" - description = "Alerts on any creation, update, or deletion of IAM groups" - compartment_id = var.tenancy_ocid # Los eventos de IAM suelen ser a nivel de Tenancy - is_enabled = true - - # La condición debe incluir explícitamente los tres tipos de eventos. - condition = jsonencode({ - eventType = [ - "com.oraclecloud.identity.creategroup", - "com.oraclecloud.identity.updategroup", - "com.oraclecloud.identity.deletegroup" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = oci_ons_notification_topic.security_alerts_topic.id - } - } -} - -# Recurso auxiliar: Tópico de notificación para enviar la alerta. -resource "oci_ons_notification_topic" "security_alerts_topic" { - compartment_id = var.compartment_id - name = "security-alerts-topic" -} \ No newline at end of file From 1ffbb164bbf2f6c9651ecf9e362dc9f426666dac Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:22 +0100 Subject: [PATCH 181/900] fix(queries): remove undocumented README.md from oci_iam_password_expiration_manual --- .../README.md | 49 ------------------- 1 file changed, 49 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_iam_password_expiration_manual/README.md diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/README.md b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/README.md deleted file mode 100644 index 930abc7a1e4..00000000000 --- a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# Regla KICS: OCI IAM Password Expiration (365 days) - -## Descripción General - -Esta regla (INFO) verifica que las contraseñas de los usuarios de IAM expiren en un plazo máximo de 365 días, alineándose con el **CIS Oracle Cloud Infrastructure Benchmark**. - -La regla maneja dos escenarios distintos dependiendo de la arquitectura de identidad utilizada en OCI: - -1. **Identity Domains (Moderno):** Audita el recurso `oci_identity_domains_password_policy`. El atributo correcto para controlar la caducidad automática es `password_expires_after`. -2. **IAM Clásico (Legacy):** Audita el recurso `oci_identity_authentication_policy`. Este recurso antiguo no permite configurar la expiración de contraseñas explícitamente a través de Terraform, por lo que requiere validación manual en la consola. - -## Lógica de la Regla - -1. **Para Identity Domains (`oci_identity_domains_password_policy`):** - * Verifica el atributo `password_expires_after`. - * Si el valor es mayor a 365 -> **Fallo**. - * Si el atributo no está definido -> **Fallo** (se asume configuración insegura/desconocida). - -2. **Para IAM Clásico (`oci_identity_authentication_policy`):** - * Genera siempre una alerta **Manual (INFO)**, indicando al auditor que debe verificar la consola de OCI. - -## Casos de Fallo Detectados - -### Caso 1: Expiración Excesiva (Identity Domains) -* **Descripción:** La política define `password_expires_after` con un valor mayor a 365 días. -* **Ubicación:** Atributo `password_expires_after`. - -### Caso 2: Atributo Faltante (Identity Domains) -* **Descripción:** Falta el atributo `password_expires_after`. -* **Ubicación:** Recurso `oci_identity_domains_password_policy`. - -### Caso 3: Recurso Legacy (Manual Check) -* **Descripción:** Se utiliza `oci_identity_authentication_policy`. -* **Ubicación:** Recurso `oci_identity_authentication_policy`. - -## Solución - -Para **Identity Domains**, establece la caducidad en 365 días o menos. - -```terraform -resource "oci_identity_domains_password_policy" "secure_policy" { - # ... otros atributos ... - idcs_endpoint = var.idcs_endpoint - - # Caducidad de contraseña en 90 días (Recomendado) - password_expires_after = 90 - - schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] -} \ No newline at end of file From bd32e6ac4cd64e6fa4d918f7d3748b161edde709 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:23 +0100 Subject: [PATCH 182/900] fix(queries): remove undocumented README.md from oci_iam_password_policy_length --- .../oci_iam_password_policy_length/README.md | 55 ------------------- 1 file changed, 55 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_iam_password_policy_length/README.md diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/README.md b/assets/queries/terraform/oci/oci_iam_password_policy_length/README.md deleted file mode 100644 index 35bfc9531ab..00000000000 --- a/assets/queries/terraform/oci/oci_iam_password_policy_length/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Regla KICS: OCI IAM Password Minimum Length - -## Descripción General - -Esta regla automatizada (MEDIUM) audita el recurso `oci_identity_authentication_policy`. - -Para garantizar una protección robusta contra ataques de fuerza bruta, el **CIS Oracle Cloud Infrastructure Benchmark** recomienda establecer la longitud mínima de la contraseña en **14 caracteres** o más. - -El valor predeterminado de OCI (si no se especifica) suele ser de 12 caracteres, lo cual es insuficiente para los estándares actuales. Esta regla alerta si: -1. La longitud se define explícitamente menor a 14. -2. Falta el atributo de longitud (usa default). -3. Falta el bloque de política de contraseñas completo (usa default). - -## Lógica de la Regla - -1. Identifica el recurso `oci_identity_authentication_policy`. -2. Verifica la existencia del bloque `password_policy`. - * Si no existe el bloque -> **Fallo** (se usa configuración insegura por defecto). -3. Si el bloque existe, verifica el atributo `minimum_password_length`: - * Si el atributo falta -> **Fallo** (se usa configuración insegura por defecto). - * Si el atributo es `< 14` -> **Fallo**. - -## Casos de Fallo Detectados - -### Caso 1: Longitud Insuficiente -* **Descripción:** Se ha configurado explícitamente `minimum_password_length` con un valor bajo (ej. 8 o 12). -* **Ubicación de la Alerta:** Atributo `minimum_password_length`. - -### Caso 2: Atributo Faltante -* **Descripción:** El bloque existe, pero falta `minimum_password_length`, aplicando el default del proveedor. -* **Ubicación de la Alerta:** Bloque `password_policy`. - -### Caso 3: Bloque Ausente -* **Descripción:** No se ha definido `password_policy` en absoluto. -* **Ubicación de la Alerta:** Recurso `oci_identity_authentication_policy`. - -## Recurso Involucrado -* `oci_identity_authentication_policy` - -## Solución - -Define el bloque `password_policy` y establece explícitamente la longitud en al menos 14. - -```terraform -resource "oci_identity_authentication_policy" "secure_policy" { - compartment_id = var.tenancy_ocid - - password_policy { - minimum_password_length = 14 - is_lowercase_characters_required = true - is_uppercase_characters_required = true - is_numeric_characters_required = true - is_special_characters_required = true - } -} \ No newline at end of file From 9f99a5b449c3c4d24e3fcce51ddd936867538f6e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:24 +0100 Subject: [PATCH 183/900] fix(queries): remove undocumented README.md from oci_iam_password_reuse_manual --- .../oci_iam_password_reuse_manual/README.md | 55 ------------------- 1 file changed, 55 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_iam_password_reuse_manual/README.md diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/README.md b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/README.md deleted file mode 100644 index 45c14e44e54..00000000000 --- a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Regla KICS: OCI IAM Password Reuse Prevention (Manual) - -## Descripción General - -Esta regla informativa (INFO) audita las políticas de contraseñas en **Oracle Cloud Infrastructure (OCI)** para asegurar que se impida la reutilización de credenciales antiguas. - -El **CIS Oracle Cloud Infrastructure Benchmark** recomienda configurar el historial de contraseñas para recordar las últimas **24** contraseñas utilizadas, evitando así que los usuarios alternen entre un conjunto pequeño de contraseñas conocidas. - -La regla maneja dos escenarios distintos dependiendo de la arquitectura de identidad utilizada en OCI: - -1. **Identity Domains (Moderno):** Audita el recurso `oci_identity_domains_password_policy`. El atributo correcto para controlar el historial es `num_passwords_in_history`. -2. **IAM Clásico (Legacy):** Audita el recurso `oci_identity_authentication_policy`. Este recurso antiguo no permite configurar el historial de contraseñas a través de Terraform, por lo que requiere validación manual en la consola. - -## Lógica de la Regla - -1. **Para Identity Domains (`oci_identity_domains_password_policy`):** - * Verifica el atributo `num_passwords_in_history`. - * Si el valor es menor a 24 -> **Fallo**. - * Si el atributo no está definido -> **Fallo** (se asume configuración insegura/desconocida). - -2. **Para IAM Clásico (`oci_identity_authentication_policy`):** - * Genera siempre una alerta **Manual (INFO)**, indicando al auditor que debe verificar la consola de OCI. - -## Casos de Fallo Detectados - -### Caso 1: Historial Insuficiente (Identity Domains) -* **Descripción:** La política define `num_passwords_in_history` con un valor menor a 24 (ej. 5 o 10). -* **Ubicación de la Alerta:** Atributo `num_passwords_in_history`. - -### Caso 2: Atributo Faltante (Identity Domains) -* **Descripción:** Falta el atributo `num_passwords_in_history`. -* **Ubicación de la Alerta:** Recurso `oci_identity_domains_password_policy`. - -### Caso 3: Recurso Legacy (Manual Check) -* **Descripción:** Se utiliza `oci_identity_authentication_policy`. -* **Ubicación de la Alerta:** Recurso `oci_identity_authentication_policy`. - -## Recursos Involucrados -* `oci_identity_domains_password_policy` -* `oci_identity_authentication_policy` - -## Solución - -Para **Identity Domains**, establece el historial en 24 o más. - -```terraform -resource "oci_identity_domains_password_policy" "secure_policy" { - idcs_endpoint = var.idcs_endpoint - display_name = "SecurePasswordPolicy" - - # Historial de contraseñas (CIS recomienda >= 24) - num_passwords_in_history = 24 - - schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] -} \ No newline at end of file From 60dfd0ff734500518e77e42d584f1d9563af9947 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:27 +0100 Subject: [PATCH 184/900] fix(queries): remove undocumented README.md from oci_iam_policy_change_event_rule_missing --- .../README.md | 65 ------------------- 1 file changed, 65 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/README.md diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/README.md deleted file mode 100644 index dfd823e140c..00000000000 --- a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# Regla KICS: Notificación para Cambios en Políticas de IAM en OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio (creación, actualización o eliminación) en las políticas de IAM de la cuenta de OCI. - -Las políticas de IAM son el mecanismo central que define "quién puede hacer qué" en OCI. Un cambio no autorizado en una política puede conceder permisos excesivos, eliminar controles de seguridad o abrir la puerta a un atacante para que tome el control de los recursos. La monitorización en tiempo real de estos cambios es, por tanto, una de las auditorías de seguridad más importantes. - -## Lógica de la Regla - -La política valida que exista una configuración activa para capturar los tres eventos críticos de políticas: -1. `com.oraclecloud.identity.createpolicy` -2. `com.oraclecloud.identity.updatepolicy` -3. `com.oraclecloud.identity.deletepolicy` - -## Casos de Fallo Detectados - ---- -### Caso 1: Regla Ausente (Missing) -* **Descripción:** No se encuentra ninguna regla de eventos que monitorice cambios en políticas de IAM en todo el proyecto. -* **Ubicación:** Bloque `provider "oci"`. - ---- -### Caso 2: Regla Incompleta (Incomplete) -* **Descripción:** Existe una regla que monitoriza algunos eventos de políticas (ej. `createpolicy`), pero omite otros críticos (ej. `deletepolicy`). -* **Ubicación:** Atributo `condition` del recurso. - ---- -### Caso 3: Regla Deshabilitada (Disabled) -* **Descripción:** Existe una regla completa con todos los eventos, pero está explícitamente deshabilitada (`is_enabled = false`). -* **Ubicación:** Atributo `is_enabled`. - -## Recurso Involucrado - -* `oci_events_rule` - -## Solución - -```terraform -resource "oci_events_rule" "iam_policy_change_rule" { - display_name = "audit-rule-for-iam-policy-changes" - description = "Alerts on any creation, update, or deletion of IAM policies" - compartment_id = var.tenancy_ocid - is_enabled = true - - condition = jsonencode({ - eventType = [ - "com.oraclecloud.identity.createpolicy", - "com.oraclecloud.identity.updatepolicy", - "com.oraclecloud.identity.deletepolicy" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = oci_ons_notification_topic.security_alerts_topic.id - } - } -} - -resource "oci_ons_notification_topic" "security_alerts_topic" { - compartment_id = var.compartment_id - name = "security-alerts-topic" -} \ No newline at end of file From 9c98e2b97ece56c0c2ef616cd1bb0bf62fc7f554 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:29 +0100 Subject: [PATCH 185/900] fix(queries): remove undocumented README.md from oci_iam_service_admins_manual --- .../oci_iam_service_admins_manual/README.md | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_iam_service_admins_manual/README.md diff --git a/assets/queries/terraform/oci/oci_iam_service_admins_manual/README.md b/assets/queries/terraform/oci/oci_iam_service_admins_manual/README.md deleted file mode 100644 index 3fedb6262a9..00000000000 --- a/assets/queries/terraform/oci/oci_iam_service_admins_manual/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Regla KICS: OCI Service Level Admins (Manual) - -## Descripción General - -Esta regla informativa (INFO) audita las políticas de **OCI IAM** (`oci_identity_policy`). - -Según el Benchmark CIS para Oracle Cloud, se debe evitar el uso excesivo del grupo de administradores predeterminado (que tiene acceso total a la tenencia). En su lugar, se deben crear **Administradores de Nivel de Servicio** (Service Level Admins). Esto implica crear grupos y políticas específicas para gestionar verticales tecnológicas, por ejemplo: -* `NetworkAdmins`: `manage virtual-network-family` -* `ComputeAdmins`: `manage instance-family` -* `StorageAdmins`: `manage object-family` - -Esta regla detecta cualquier política que otorgue el verbo `manage` para que un auditor verifique que está correctamente acotada (es decir, que no sea `manage all-resources` a menos que sea estrictamente necesario). - -## Lógica de la Regla - -1. Identifica recursos `oci_identity_policy`. -2. Analiza el array `statements`. -3. Si una sentencia contiene la palabra exacta `manage` (usando detección de límite de palabra y sin distinguir mayúsculas/minúsculas), genera una alerta para su revisión manual. - -## Casos de Fallo Detectados - -### Caso 1: Privilegios de Gestión (Manage) - -* **Descripción:** Se detectó una política que otorga control total (`manage`) sobre algún recurso o familia de recursos. -* **Acción:** Verificar que el grupo asignado y el recurso gestionado ("family") corresponden a una segregación de funciones adecuada. -* **Ubicación de la Alerta:** Atributo `statements` en `oci_identity_policy`. - -## Recurso Involucrado - -* `oci_identity_policy` - -## Solución - -Define políticas granulares por familia de servicios. - -```terraform -resource "oci_identity_policy" "network_admin_policy" { - name = "NetworkAdminPolicy" - description = "Policy for Network Admins" - compartment_id = var.tenancy_ocid - - statements = [ - "Allow group NetworkAdmins to manage virtual-network-family in tenancy", - "Allow group NetworkAdmins to read all-resources in tenancy" - ] -} \ No newline at end of file From f984f0e5f53d50cc30eb6a88c6cf756a13e6bd85 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:31 +0100 Subject: [PATCH 186/900] fix(queries): remove undocumented README.md from oci_iam_user_change_event_rule_missing --- .../README.md | 57 ------------------- 1 file changed, 57 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/README.md diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/README.md deleted file mode 100644 index 641c35d5c0a..00000000000 --- a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# Regla KICS: Notificación para Cambios en Usuarios de IAM en OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio en el ciclo de vida de los usuarios de IAM en la cuenta de OCI. - -La gestión de identidades de usuario es una superficie de ataque principal. Un atacante podría crear un usuario nuevo y oculto, modificar un usuario existente para escalar privilegios, o deshabilitar cuentas legítimas para causar una denegación de servicio. - -## Lógica de la Regla - -La política verifica que exista configuración activa para capturar los cinco tipos de eventos que constituyen el ciclo de vida de un usuario de IAM: -1. `com.oraclecloud.identity.createuser` -2. `com.oraclecloud.identity.updateuser` -3. `com.oraclecloud.identity.deleteuser` -4. `com.oraclecloud.identity.enableuser` -5. `com.oraclecloud.identity.disableuser` - -## Casos de Fallo Detectados - -### Caso 1: Regla Ausente (Missing) -* **Descripción:** No existe ninguna regla configurada para usuarios en el proyecto. -* **Ubicación:** Bloque `provider "oci"`. - -### Caso 2: Regla Incompleta (Incomplete) -* **Descripción:** Existe una regla para usuarios, pero le faltan eventos (ej. monitorea `create` pero olvida `disable`). -* **Ubicación:** Atributo `condition`. - -### Caso 3: Regla Deshabilitada (Disabled) -* **Descripción:** Existe una regla relevante pero está explícitamente deshabilitada (`is_enabled = false`). -* **Ubicación:** Atributo `is_enabled` dentro del recurso `oci_events_rule`. - -## Solución - -```terraform -resource "oci_events_rule" "iam_user_change_rule" { - display_name = "audit-rule-for-iam-user-changes" - description = "Alerts on any lifecycle change of IAM users" - compartment_id = var.tenancy_ocid - is_enabled = true - - condition = jsonencode({ - eventType = [ - "com.oraclecloud.identity.createuser", - "com.oraclecloud.identity.updateuser", - "com.oraclecloud.identity.deleteuser", - "com.oraclecloud.identity.enableuser", - "com.oraclecloud.identity.disableuser" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = oci_ons_notification_topic.security_alerts_topic.id - } - } -} \ No newline at end of file From 6a99cd7f9c7d17c45c2e96e6680db4ef2b19959e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:32 +0100 Subject: [PATCH 187/900] fix(queries): remove undocumented README.md from oci_idp_change_event_rule_missing --- .../README.md | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_idp_change_event_rule_missing/README.md diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/README.md deleted file mode 100644 index aee2de0105c..00000000000 --- a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Regla KICS: Notificación para Cambios en el Proveedor de Identidad de OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cambios en los proveedores de identidad (Identity Providers) de la cuenta de OCI. - -Los proveedores de identidad son un componente crítico de la seguridad, ya que controlan la federación de usuarios. Un atacante que consiga modificar o añadir un proveedor de identidad podría redirigir los inicios de sesión o federar un dominio malicioso para obtener acceso a la cuenta. Por lo tanto, cualquier cambio en esta configuración debe ser notificado y auditado inmediatamente. - -## Lógica de la Regla - -La política verifica que exista configuración activa para capturar el siguiente evento crítico: -* `com.oraclecloud.identitycontrolplane.updateidentityprovider` - -## Casos de Fallo Detectados - -### Caso 1: Regla Ausente (Missing) -* **Descripción:** No existe ninguna regla configurada para monitorear Identity Providers en el proyecto. -* **Ubicación de la Alerta:** Bloque `provider "oci"`. - -### Caso 2: Regla Deshabilitada (Disabled) -* **Descripción:** Existe una regla que monitorea el evento correcto, pero está explícitamente deshabilitada (`is_enabled = false`). -* **Ubicación de la Alerta:** Atributo `is_enabled` dentro del recurso `oci_events_rule`. - -## Solución - -Para solucionar el problema, asegúrate de tener una regla habilitada con el evento correcto: - -```terraform -resource "oci_events_rule" "iam_idp_change_rule" { - display_name = "audit-rule-for-identity-provider-changes" - description = "Alerts on any modification to Identity Providers" - compartment_id = var.tenancy_ocid - is_enabled = true - - condition = jsonencode({ - eventType = [ - "com.oraclecloud.identitycontrolplane.updateidentityprovider" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = oci_ons_notification_topic.security_alerts_topic.id - } - } -} \ No newline at end of file From 2d690edc5c75cd7e357053aa7e359917c96e6708 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:34 +0100 Subject: [PATCH 188/900] fix(queries): remove undocumented README.md from oci_idp_group_mapping_change_event_rule_missing --- .../README.md | 45 ------------------- 1 file changed, 45 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/README.md diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/README.md deleted file mode 100644 index 79e56c40b98..00000000000 --- a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Regla KICS: Notificación para Cambios de Mapeo de Grupos de IdP en OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cambios en los mapeos de grupos de los proveedores de identidad (IdP) de la cuenta de OCI. - -El mapeo de grupos de un IdP es lo que traduce la pertenencia a un grupo en un proveedor de identidad externo (como Azure AD, Okta, etc.) a la pertenencia a un grupo de IAM en OCI. Un cambio no autorizado en estos mapeos podría escalar privilegios de forma masiva y silenciosa. - -## Lógica de la Regla - -La política verifica que exista configuración activa para capturar el siguiente evento crítico: -* `com.oraclecloud.identitycontrolplane.updateidpgroupmapping` - -## Casos de Fallo Detectados - -### Caso 1: Regla Ausente (Missing) -* **Descripción:** No existe ninguna regla configurada para monitorear cambios en mapeos de grupos de IdP. -* **Ubicación de la Alerta:** Bloque `provider "oci"`. - -### Caso 2: Regla Deshabilitada (Disabled) -* **Descripción:** Existe una regla que monitorea el evento correcto, pero está explícitamente deshabilitada (`is_enabled = false`). -* **Ubicación de la Alerta:** Atributo `is_enabled` dentro del recurso `oci_events_rule`. - -## Solución - -```terraform -resource "oci_events_rule" "iam_idp_group_mapping_change_rule" { - display_name = "audit-rule-for-idp-group-mapping-changes" - description = "Alerts on any modification to IdP group mappings" - compartment_id = var.tenancy_ocid - is_enabled = true - - condition = jsonencode({ - eventType = [ - "com.oraclecloud.identitycontrolplane.updateidpgroupmapping" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = oci_ons_notification_topic.security_alerts_topic.id - } - } -} \ No newline at end of file From 4b2b3070d78177658cbcf4f02eeac7950f8dd8b4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:35 +0100 Subject: [PATCH 189/900] fix(queries): remove undocumented README.md from oci_instance_transit_encryption --- .../oci_instance_transit_encryption/README.md | 54 ------------------- 1 file changed, 54 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_instance_transit_encryption/README.md diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/README.md b/assets/queries/terraform/oci/oci_instance_transit_encryption/README.md deleted file mode 100644 index 3d6ee853be2..00000000000 --- a/assets/queries/terraform/oci/oci_instance_transit_encryption/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# Regla KICS: OCI Instance In-Transit Encryption Disabled - -## Descripción General - -Esta regla de severidad **MEDIA** audita el recurso `oci_core_instance` para verificar que el cifrado en tránsito esté habilitado. - -En OCI, la opción `is_pv_encryption_in_transit_enabled` dentro de `launch_options` habilita el cifrado de los datos transferidos entre la instancia de computación y los volúmenes de arranque o de bloques paravirtualizados. Esto asegura la confidencialidad de los datos mientras viajan por la red interna del centro de datos. - -## Lógica de la Regla - -La regla verifica tres escenarios distintos: - -1. **Valor Incorrecto:** El bloque `launch_options` existe y el atributo `is_pv_encryption_in_transit_enabled` está explícitamente en `false`. -2. **Atributo Faltante:** El bloque `launch_options` existe, pero falta el atributo `is_pv_encryption_in_transit_enabled` (lo que puede aplicar un valor por defecto inseguro). -3. **Bloque Faltante:** No existe el bloque `launch_options` en la definición del recurso. - -## Casos de Fallo Detectados - -### Caso 1: Cifrado Deshabilitado Explícitamente -* **Descripción:** Se ha configurado `is_pv_encryption_in_transit_enabled = false`. -* **Ubicación de la Alerta:** Atributo `is_pv_encryption_in_transit_enabled`. - -### Caso 2: Atributo Faltante en Opciones -* **Descripción:** El bloque `launch_options` está definido, pero no se especifica el cifrado, confiando en el valor predeterminado del proveedor. -* **Ubicación de la Alerta:** Bloque `launch_options`. - -### Caso 3: Bloque de Opciones Ausente -* **Descripción:** La instancia no define `launch_options`, por lo que no se está forzando el cifrado en tránsito. -* **Ubicación de la Alerta:** Recurso `oci_core_instance`. - -## Recurso Involucrado -* `oci_core_instance` - -## Solución - -Habilita explícitamente el cifrado en tránsito dentro de las opciones de lanzamiento. - -```terraform -resource "oci_core_instance" "secure_instance" { - availability_domain = var.availability_domain - compartment_id = var.compartment_id - shape = "VM.Standard.E4.Flex" - - # Bloque requerido para la seguridad en tránsito - launch_options { - boot_volume_type = "PARAVIRTUALIZED" - is_pv_encryption_in_transit_enabled = true - } - - source_details { - source_type = "image" - source_id = var.image_id - } -} \ No newline at end of file From 167bb241f3d4de7df35c5d53d06ed1c0194d54b9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:36 +0100 Subject: [PATCH 190/900] fix(queries): remove undocumented README.md from oci_local_user_authentication_event_rule_missing --- .../README.md | 45 ------------------- 1 file changed, 45 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/README.md diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/README.md deleted file mode 100644 index dc40f8f9440..00000000000 --- a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Regla KICS: Notificación para Autenticación de Usuarios Locales en OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para generar notificaciones cada vez que un usuario local de IAM (no federado) se autentica en la cuenta de OCI. - -Los usuarios locales de IAM son aquellos definidos directamente en OCI. Monitorizar sus inicios de sesión es una medida de seguridad fundamental para detectar actividad sospechosa, como inicios de sesión desde ubicaciones inusuales o intentos de fuerza bruta. - -## Lógica de la Regla - -La política verifica que exista configuración activa para capturar el siguiente evento crítico: -* `com.oraclecloud.identity.localuser.authenticate` - -## Casos de Fallo Detectados - -### Caso 1: Regla Ausente (Missing) -* **Descripción:** No existe ninguna regla configurada para monitorear la autenticación de usuarios locales. -* **Ubicación de la Alerta:** Bloque `provider "oci"`. - -### Caso 2: Regla Deshabilitada (Disabled) -* **Descripción:** Existe una regla que monitorea el evento correcto, pero está explícitamente deshabilitada (`is_enabled = false`). -* **Ubicación de la Alerta:** Atributo `is_enabled` dentro del recurso `oci_events_rule`. - -## Solución - -```terraform -resource "oci_events_rule" "local_user_auth_rule" { - display_name = "audit-rule-for-local-user-authentication" - description = "Alerts on any local IAM user authentication event" - compartment_id = var.tenancy_ocid - is_enabled = true - - condition = jsonencode({ - eventType = [ - "com.oraclecloud.identity.localuser.authenticate" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = oci_ons_notification_topic.security_alerts_topic.id - } - } -} \ No newline at end of file From 030d2cc3015e2b5c024fe8ad69ae127d855041a3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:38 +0100 Subject: [PATCH 191/900] fix(queries): remove undocumented README.md from oci_network_gateway_change_event_rule_missing --- .../README.md | 67 ------------------- 1 file changed, 67 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/README.md diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/README.md deleted file mode 100644 index 6c44e75e559..00000000000 --- a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# Regla KICS: Notificación para Cambios en Gateways de Red en OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio (creación, actualización o eliminación) en los gateways de red de la cuenta de OCI. - -Los gateways de red (Internet Gateway, NAT Gateway, Service Gateway, DRG, LPG) son los puntos de entrada y salida del tráfico de una VCN. - -## Lógica de la Regla - -La política verifica que exista configuración activa para capturar los 15 eventos relacionados con el ciclo de vida de: -* Internet Gateway -* NAT Gateway -* Service Gateway -* Dynamic Routing Gateway (DRG) -* Local Peering Gateway (LPG) - -## Casos de Fallo Detectados - -### Caso 1: Regla Ausente (Missing) -* **Descripción:** No existe ninguna regla configurada para gateways en el proyecto. -* **Ubicación:** Bloque `provider "oci"`. - -### Caso 2: Regla Incompleta (Incomplete) -* **Descripción:** Existe una regla para gateways, pero le faltan tipos de eventos (ej. monitoriza Internet Gateway pero olvida DRG). -* **Ubicación:** Atributo `condition`. - -### Caso 3: Regla Deshabilitada (Disabled) -* **Descripción:** Existe una regla relevante pero está explícitamente deshabilitada (`is_enabled = false`). -* **Ubicación:** Atributo `is_enabled`. - -## Solución - -```terraform -resource "oci_events_rule" "network_gateway_change_rule" { - display_name = "audit-rule-for-network-gateway-changes" - description = "Alerts on any creation, update, or deletion of Network Gateways" - compartment_id = var.tenancy_ocid - is_enabled = true - - condition = jsonencode({ - eventType = [ - "com.oraclecloud.virtualnetwork.createinternetgateway", - "com.oraclecloud.virtualnetwork.updateinternetgateway", - "com.oraclecloud.virtualnetwork.deleteinternetgateway", - "com.oraclecloud.virtualnetwork.createnatgateway", - "com.oraclecloud.virtualnetwork.updatenatgateway", - "com.oraclecloud.virtualnetwork.deletenatgateway", - "com.oraclecloud.virtualnetwork.createservicegateway", - "com.oraclecloud.virtualnetwork.updateservicegateway", - "com.oraclecloud.virtualnetwork.deleteservicegateway", - "com.oraclecloud.virtualnetwork.createdrg", - "com.oraclecloud.virtualnetwork.updatedrg", - "com.oraclecloud.virtualnetwork.deletedrg", - "com.oraclecloud.virtualnetwork.createlocalpeeringgateway", - "com.oraclecloud.virtualnetwork.updatelocalpeeringgateway", - "com.oraclecloud.virtualnetwork.deletelocalpeeringgateway" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = oci_ons_notification_topic.security_alerts_topic.id - } - } -} \ No newline at end of file From 7bed60152d42aa3cd1c2da452d18eaa85c62e7d4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:39 +0100 Subject: [PATCH 192/900] fix(queries): remove undocumented README.md from oci_notification_topic_without_subscription --- .../README.md | 44 ------------------- 1 file changed, 44 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_notification_topic_without_subscription/README.md diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/README.md b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/README.md deleted file mode 100644 index b76a8721257..00000000000 --- a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# Regla KICS: Tópicos de Notificación con Suscripción en OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que los tópicos de notificación del servicio OCI Notifications (`oci_ons_notification_topic`) tengan al menos una suscripción (`oci_ons_subscription`) asociada. - -El servicio de notificaciones de OCI se usa para desacoplar componentes y enviar alertas. Un "tópico" es el canal al que se publican los mensajes, pero sin una "suscripción" (email, función, webhook, etc.), esos mensajes no se entregan a ningún destino y se pierden. - -## Lógica de la Regla - -La política se divide en dos reglas para cubrir los posibles escenarios de fallo: -1. **Ausencia Global:** No hay tópicos de notificación definidos. -2. **Tópico Huérfano:** Existe un tópico que no está referenciado por ninguna suscripción. - -## Casos de Fallo Detectados - -### Caso 1: Recurso `oci_ons_notification_topic` Ausente -* **Descripción:** No se encuentra ni un solo recurso de tipo `oci_ons_notification_topic` en el proyecto. -* **Ubicación de la Alerta:** Bloque `provider "oci"`. - -### Caso 2: Tópico sin Suscripciones Asociadas -* **Descripción:** Existe un recurso `oci_ons_notification_topic`, pero no existe ningún `oci_ons_subscription` cuyo `topic_id` apunte a él. -* **Ubicación de la Alerta:** Recurso `oci_ons_notification_topic`. - -## Solución - -Asegúrate de que exista al menos un tópico y que tenga una suscripción enlazada: - -```terraform -resource "oci_ons_notification_topic" "critical_alerts" { - compartment_id = var.compartment_id - name = "my-critical-alerts-topic" -} - -# RECURSO REQUERIDO: La suscripción que enlaza al tópico -resource "oci_ons_subscription" "email_subscription" { - compartment_id = var.compartment_id - - # Referencia cruzada al tópico - topic_id = oci_ons_notification_topic.critical_alerts.id - - protocol = "EMAIL" - endpoint = "ops-team@example.com" -} \ No newline at end of file From 7683f995ef754210b9b557d0eff899c9a937effd Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:40 +0100 Subject: [PATCH 193/900] fix(queries): remove undocumented README.md from oci_nsg_change_event_rule_missing --- .../README.md | 53 ------------------- 1 file changed, 53 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/README.md diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/README.md deleted file mode 100644 index e137c8f098a..00000000000 --- a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# Regla KICS: Notificación para Cambios en Grupos de Seguridad de Red (NSG) en OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio (creación, actualización o eliminación) en los Grupos de Seguridad de Red (NSG) de la cuenta de OCI. - -Los NSG proporcionan un firewall virtual para un conjunto de recursos. Un cambio no autorizado en un NSG podría exponer una aplicación a internet o permitir movimientos laterales no deseados. - -## Lógica de la Regla - -La política verifica que exista configuración activa para capturar los tres tipos de eventos críticos de NSG: -1. `com.oraclecloud.virtualnetwork.createnetworksecuritygroup` -2. `com.oraclecloud.virtualnetwork.updatenetworksecuritygroup` -3. `com.oraclecloud.virtualnetwork.deletenetworksecuritygroup` - -## Casos de Fallo Detectados - -### Caso 1: Regla Ausente (Missing) -* **Descripción:** No existe ninguna regla configurada para NSGs en el proyecto. -* **Ubicación de la Alerta:** Bloque `provider "oci"`. - -### Caso 2: Regla Incompleta (Incomplete) -* **Descripción:** Existe una regla para NSGs, pero le faltan eventos (ej. monitoriza create pero olvida delete). -* **Ubicación de la Alerta:** Atributo `condition`. - -### Caso 3: Regla Deshabilitada (Disabled) -* **Descripción:** Existe una regla relevante pero está explícitamente deshabilitada (`is_enabled = false`). -* **Ubicación de la Alerta:** Atributo `is_enabled` dentro del recurso. - -## Solución - -```terraform -resource "oci_events_rule" "nsg_change_rule" { - display_name = "audit-rule-for-nsg-changes" - description = "Alerts on any creation, update, or deletion of Network Security Groups" - compartment_id = var.tenancy_ocid - is_enabled = true - - condition = jsonencode({ - eventType = [ - "com.oraclecloud.virtualnetwork.createnetworksecuritygroup", - "com.oraclecloud.virtualnetwork.updatenetworksecuritygroup", - "com.oraclecloud.virtualnetwork.deletenetworksecuritygroup" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = oci_ons_notification_topic.security_alerts_topic.id - } - } -} \ No newline at end of file From 297e2c3ee050e98ecf433d59e8f392dd63da1d32 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:42 +0100 Subject: [PATCH 194/900] fix(queries): remove undocumented README.md from oci_objectstorage_bucket_logging_enabled --- .../README.md | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/README.md diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/README.md b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/README.md deleted file mode 100644 index 8fe00ec4c3b..00000000000 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Regla KICS: Logging de Escritura en OCI Object Storage - -## Descripción General - -Esta regla de KICS para Terraform asegura que todos los buckets de OCI Object Storage (`oci_objectstorage_bucket`) tengan habilitada la emisión de eventos para objetos. Esta funcionalidad es fundamental para el logging de operaciones de escritura, como la creación (`put`), sobreescritura y eliminación de objetos. - -Auditar quién modifica o elimina datos es un requisito de seguridad y cumplimiento normativo crítico. Esta política verifica los dos escenarios posibles de mala configuración para proporcionar alertas precisas. - -## Lógica de la Regla - -La política se compone de dos reglas especializadas que cubren todos los casos en los que el logging de eventos de objeto está desactivado. - -## Casos de Fallo Detectados - -### Caso 1: Atributo `object_events_enabled` Ausente - -* **Descripción:** Esta regla detecta cualquier recurso `oci_objectstorage_bucket` donde el atributo `object_events_enabled` no está definido. El valor por defecto es `false`. -* **Ubicación de la Alerta:** Recurso `oci_objectstorage_bucket`. - -### Caso 2: Atributo `object_events_enabled` es `false` - -* **Descripción:** Esta regla busca un recurso `oci_objectstorage_bucket` que tiene el atributo `object_events_enabled` explícitamente configurado como `false`. -* **Ubicación de la Alerta:** Atributo `object_events_enabled`. - -## Solución - -Para solucionar los problemas detectados por esta regla, asegúrate de que cada recurso `oci_objectstorage_bucket` incluya la siguiente línea: - -```terraform -resource "oci_objectstorage_bucket" "example" { - # ... otros atributos ... - - object_events_enabled = true -} \ No newline at end of file From 8ea48cf9380d19d2f0d3c615d0f170f3eaf5fd49 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:43 +0100 Subject: [PATCH 195/900] fix(queries): remove undocumented README.md from oci_objectstorage_bucket_versioning_disabled --- .../README.md | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/README.md diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/README.md b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/README.md deleted file mode 100644 index e356a9823d2..00000000000 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Regla KICS: Versionado Habilitado para Buckets de Object Storage en OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que todos los buckets de OCI Object Storage (`oci_objectstorage_bucket`) tengan habilitada la funcionalidad de versionado. - -El versionado es una capa de protección de datos fundamental. Cuando está habilitado, cualquier modificación (sobrescritura) o eliminación de un objeto no lo destruye permanentemente, sino que crea una nueva versión o un marcador de eliminación. Esto permite recuperar fácilmente versiones anteriores de un objeto en caso de un borrado accidental o una modificación no deseada, actuando como una red de seguridad contra la pérdida de datos. - -## Lógica de la Regla - -La política se compone de dos reglas para cubrir los escenarios en los que el versionado está desactivado, centradas en el atributo `versioning`. - -## Casos de Fallo Detectados - -### Caso 1: Atributo `versioning` Ausente - -* **Descripción:** Esta regla detecta cualquier recurso `oci_objectstorage_bucket` donde el atributo `versioning` no está definido. Si se omite, el versionado no se habilita por defecto. -* **Ubicación de la Alerta:** Recurso `oci_objectstorage_bucket`. - -### Caso 2: Atributo `versioning` no es `Enabled` - -* **Descripción:** Esta regla busca un recurso `oci_objectstorage_bucket` que tiene el atributo `versioning` explícitamente configurado con un valor diferente a `"Enabled"` (por ejemplo, `"Suspended"` o `"Disabled"`). -* **Ubicación de la Alerta:** Atributo `versioning`. - -## Solución - -Para solucionar los problemas detectados, asegúrate de que cada recurso `oci_objectstorage_bucket` incluya el atributo `versioning` con el valor `"Enabled"`. - -```terraform -resource "oci_objectstorage_bucket" "example" { - # ... otros atributos ... - - versioning = "Enabled" -} \ No newline at end of file From 573c0e9c209d10eb20a5f018740cf64e17e7969a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:44 +0100 Subject: [PATCH 196/900] fix(queries): remove undocumented README.md from oci_resource_created_in_root_compartment --- .../README.md | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_resource_created_in_root_compartment/README.md diff --git a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/README.md b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/README.md deleted file mode 100644 index e9d61f3d55d..00000000000 --- a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Regla KICS: Recursos Creados Fuera del Compartimento Raíz en OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que los recursos no se creen directamente en el compartimento raíz (también conocido como *tenancy*). - -El compartimento raíz tiene los máximos privilegios y debe mantenerse lo más limpio posible, conteniendo únicamente otros compartimentos y políticas de IAM a nivel de *tenancy*. Crear recursos operativos (como instancias de cómputo, redes virtuales o bases de datos) en el compartimento raíz viola los principios de **menor privilegio**. - -## Lógica de la Regla - -La política mantiene una lista interna de tipos de recursos auditables. Itera sobre todos los recursos definidos en la configuración de Terraform y, si un recurso es de un tipo auditable, verifica el valor de su `compartment_id`. - -La regla se activa si el `compartment_id` apunta al compartimento raíz. Esto se detecta de dos maneras: -1. Si el valor es una referencia a `var.tenancy_ocid`. -2. Si el propio valor del OCID contiene la palabra `tenancy` (case-insensitive). - -## Caso de Fallo Detectado - -### Caso Único: Recurso con `compartment_id` apuntando al Raíz -* **Descripción:** Un recurso de la lista auditable tiene su `compartment_id` asignado al OCID del *tenancy*. -* **Ubicación de la Alerta:** Atributo `compartment_id`. - -## Solución - -Asegúrate de que todos los recursos se creen en compartimentos hijos apropiados. - -```terraform -variable "networking_compartment_ocid" {} - -# Esta VCN se crea en un compartimento hijo dedicado, lo cual es correcto. -resource "oci_core_vcn" "example_vcn_correct" { - compartment_id = var.networking_compartment_ocid - display_name = "VcnInNetworkingCompartment" - cidr_block = "10.1.0.0/16" -} \ No newline at end of file From 12a4b71208419160e5c011310fe38ae3db48ea15 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:45 +0100 Subject: [PATCH 197/900] fix(queries): remove undocumented README.md from oci_route_table_change_event_rule_missing --- .../README.md | 53 ------------------- 1 file changed, 53 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/README.md diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/README.md deleted file mode 100644 index bd96ad8138f..00000000000 --- a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# Regla KICS: Notificación para Cambios en Tablas de Enrutamiento en OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio (creación, actualización o eliminación) en las Tablas de Enrutamiento (Route Tables) de la cuenta de OCI. - -Las tablas de enrutamiento controlan el flujo del tráfico de red entre subredes . Un cambio no autorizado podría redirigir el tráfico maliciosamente. - -## Lógica de la Regla - -La política verifica que exista configuración activa para capturar los tres tipos de eventos críticos de Route Tables: -1. `com.oraclecloud.virtualnetwork.createroutetable` -2. `com.oraclecloud.virtualnetwork.updateroutetable` -3. `com.oraclecloud.virtualnetwork.deleteroutetable` - -## Casos de Fallo Detectados - -### Caso 1: Regla Ausente (Missing) -* **Descripción:** No existe ninguna regla configurada para Route Tables en el proyecto. -* **Ubicación de la Alerta:** Bloque `provider "oci"`. - -### Caso 2: Regla Incompleta (Incomplete) -* **Descripción:** Existe una regla para Route Tables, pero le faltan eventos (ej. monitoriza create pero olvida delete). -* **Ubicación de la Alerta:** Atributo `condition`. - -### Caso 3: Regla Deshabilitada (Disabled) -* **Descripción:** Existe una regla relevante pero está explícitamente deshabilitada (`is_enabled = false`). -* **Ubicación de la Alerta:** Atributo `is_enabled` dentro del recurso. - -## Solución - -```terraform -resource "oci_events_rule" "route_table_change_rule" { - display_name = "audit-rule-for-route-table-changes" - description = "Alerts on any creation, update, or deletion of Route Tables" - compartment_id = var.tenancy_ocid - is_enabled = true - - condition = jsonencode({ - eventType = [ - "com.oraclecloud.virtualnetwork.createroutetable", - "com.oraclecloud.virtualnetwork.updateroutetable", - "com.oraclecloud.virtualnetwork.deleteroutetable" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = oci_ons_notification_topic.security_alerts_topic.id - } - } -} \ No newline at end of file From 5f813123fa956e328d060d6bc23080a20a42c4d2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:47 +0100 Subject: [PATCH 198/900] fix(queries): remove undocumented README.md from oci_security_list_change_event_rule_missing --- .../README.md | 54 ------------------- 1 file changed, 54 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/README.md diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/README.md deleted file mode 100644 index 5aeef264100..00000000000 --- a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# Regla KICS: Notificación para Cambios en Listas de Seguridad en OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio (creación, actualización o eliminación) en las Listas de Seguridad (Security Lists) de la cuenta de OCI. - -Las Listas de Seguridad actúan como un firewall virtual a nivel de subred. Un cambio no autorizado, como añadir una regla que permita el acceso desde cualquier IP (`0.0.0.0/0`) a un puerto de gestión, puede exponer gravemente la infraestructura. - -## Lógica de la Regla - -La política verifica la configuración de los recursos `oci_events_rule` buscando los tres tipos de eventos fundamentales: -* `com.oraclecloud.virtualnetwork.createsecuritylist` -* `com.oraclecloud.virtualnetwork.updatesecuritylist` -* `com.oraclecloud.virtualnetwork.deletesecuritylist` - -## Casos de Fallo Detectados - -### Caso 1: Regla Ausente (Missing) -* **Descripción:** No existe ninguna regla en la configuración que monitorice cambios en Security Lists. -* **Ubicación:** Bloque `provider "oci"`. - -### Caso 2: Regla Incompleta (Incomplete) -* **Descripción:** Existe una regla pero no incluye los tres eventos requeridos (create, update, delete). -* **Ubicación:** Atributo `condition`. - -### Caso 3: Regla Deshabilitada (Disabled) -* **Descripción:** Existe una regla relevante pero el atributo `is_enabled` es `false`. -* **Ubicación:** Atributo `is_enabled`. - -## Solución - -Asegúrate de incluir una regla habilitada con los eventos correspondientes: - -```terraform -resource "oci_events_rule" "security_list_change_rule" { - display_name = "audit-rule-for-security-list-changes" - compartment_id = var.tenancy_ocid - is_enabled = true - - condition = jsonencode({ - eventType = [ - "com.oraclecloud.virtualnetwork.createsecuritylist", - "com.oraclecloud.virtualnetwork.updatesecuritylist", - "com.oraclecloud.virtualnetwork.deletesecuritylist" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = oci_ons_notification_topic.security_alerts_topic.id - } - } -} \ No newline at end of file From 8f1d32c0914d872f37210999817ac09f98827b44 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:48 +0100 Subject: [PATCH 199/900] fix(queries): remove undocumented README.md from oci_storage_admin_no_delete_manual --- .../README.md | 40 ------------------- 1 file changed, 40 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/README.md diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/README.md b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/README.md deleted file mode 100644 index 63a02d7b3d2..00000000000 --- a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# Regla KICS: OCI Storage Admin with Delete Privileges (Manual) - -## Descripción General - -Esta regla informativa (INFO) audita las políticas de IAM (`oci_identity_policy`) para identificar administradores de almacenamiento con permisos excesivos, específicamente la capacidad de borrar recursos. - -En OCI, el verbo **`manage`** incluye todos los permisos: `inspect`, `read`, `use`, `create`, `update` y **`DELETE`**. Para cumplir con controles estrictos de protección de datos, los administradores de almacenamiento no deberían tener capacidad para eliminar volúmenes o buckets por defecto, o esta capacidad debería estar restringida mediante condiciones. - -## Lógica de la Regla - -1. Analiza las sentencias (`statements`) de las políticas. -2. Busca la combinación del verbo exacto `manage` con familias de almacenamiento: - * `object-family` - * `volume-family` - * `file-family` - * `autonomous-database-family` -3. Genera una alerta INFO para revisión manual si se detecta acceso total de gestión. - -## Casos de Fallo Detectados - -### Caso 1: Gestión Total de Almacenamiento -* **Descripción:** Se otorga `manage` sobre una familia de almacenamiento sin restricciones visibles en la sentencia. -* **Acción:** Verificar si el usuario realmente requiere capacidad de borrado o si se puede añadir una cláusula `where request.permission != 'DELETE'`. - -## Recursos Involucrados -* `oci_identity_policy` - -## Solución - -Añade una condición a la política para restringir el borrado. - -```terraform -resource "oci_identity_policy" "storage_admin_safe" { - name = "SafeStorageAdmin" - compartment_id = var.tenancy_ocid - statements = [ - # Permite gestionar todo EXCEPTO borrar - "Allow group StorageAdmins to manage object-family in tenancy where request.permission != 'DELETE'" - ] -} \ No newline at end of file From 26d1b17505484ba109ad395051ec23c206648726 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:49 +0100 Subject: [PATCH 200/900] fix(queries): remove undocumented README.md from oci_storage_cmk_encryption_unified --- .../README.md | 40 ------------------- 1 file changed, 40 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/README.md diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/README.md b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/README.md deleted file mode 100644 index 175b79913f5..00000000000 --- a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# Regla KICS: OCI Storage Resources Without CMK - -## Descripción General - -Esta regla unificada de severidad **MEDIA** audita los recursos de almacenamiento de OCI para asegurar que utilicen claves gestionadas por el cliente (CMK). - -Aunque OCI cifra los datos en reposo por defecto, lo hace con claves gestionadas por Oracle. Para tener control total sobre el ciclo de vida de la clave (rotación, revocación), es necesario asignar una clave de **OCI Vault** mediante el atributo `kms_key_id`. - -## Lógica de la Regla - -La política verifica los siguientes recursos: -* `oci_objectstorage_bucket` -* `oci_core_volume` -* `oci_core_boot_volume` -* `oci_file_storage_file_system` - -La regla se activa si: -1. El atributo `kms_key_id` no está definido. -2. El atributo `kms_key_id` está presente pero tiene un valor vacío. - -## Casos de Fallo Detectados - -### Caso 1: Cifrado por Defecto (Oracle-Managed) -* **Descripción:** El recurso no define `kms_key_id`, delegando el control de la clave a Oracle. -* **Ubicación de la Alerta:** Bloque del recurso. - -### Caso 2: Configuración Vacía -* **Descripción:** Se define el atributo pero no se proporciona un OCID válido. -* **Ubicación de la Alerta:** Atributo `kms_key_id`. - -## Solución - -Asigna el OCID de una clave de OCI Vault al recurso. - -```terraform -resource "oci_objectstorage_bucket" "secure_bucket" { - name = "secure-bucket" - compartment_id = var.compartment_id - kms_key_id = "ocid1.key.oc1.iad.exampleuniqueID" -} \ No newline at end of file From f4bc63e5d73770af423cb06912cef293530ce532 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:50 +0100 Subject: [PATCH 201/900] fix(queries): remove undocumented README.md from oci_subnet_flow_logging_disabled --- .../README.md | 56 ------------------- 1 file changed, 56 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/README.md diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/README.md b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/README.md deleted file mode 100644 index 5143fc1f110..00000000000 --- a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# Regla KICS: VCN Flow Logging Habilitado - -## Descripción General - -Esta regla de KICS para Terraform asegura que todas las subredes de una VCN (Virtual Cloud Network) en OCI tengan el registro de flujos (`Flow Logging`) correctamente configurado y habilitado. - -La monitorización del tráfico de red es crucial para la detección de anomalías y la resolución de incidentes, cumpliendo con las recomendaciones de seguridad CIS. - -## Lógica de la Regla - -La política se divide en cuatro comprobaciones: -1. **Huérfano:** Subredes sin ningún recurso de log que las apunte. -2. **Estado:** Logs de flujo marcados como `is_enabled = false`. -3. **Tipo:** Logs de servicio que no usan el `log_type = "SERVICE"`. -4. **Servicio:** Logs que no especifican `service = "flowlogs"` en su origen. - -## Casos de Fallo Detectados - -### Caso 1: Subred sin Log Asociado -* **Descripción:** Falta la definición del log para la subred. -* **Ubicación:** Recurso `oci_core_subnet`. - -### Caso 2: Log de Flujo Deshabilitado -* **Descripción:** El atributo `is_enabled` está en `false`. -* **Ubicación:** Atributo `is_enabled` en `oci_logging_log`. - -### Caso 3: Log de Flujo con el Tipo Incorrecto -* **Descripción:** `log_type` no es `"SERVICE"`. -* **Ubicación:** Atributo `log_type` en `oci_logging_log`. - -### Caso 4: Log de Flujo con el Servicio Incorrecto -* **Descripción:** El servicio configurado no es `"flowlogs"`. -* **Ubicación:** Atributo `service` dentro del bloque `source`. - -## Recursos Involucrados - -* `oci_core_subnet` -* `oci_logging_log` - -## Solución - -```terraform -resource "oci_logging_log" "vcn_flow_log" { - display_name = "subnet_flow_log" - log_group_id = oci_logging_log_group.example_log_group.id - log_type = "SERVICE" - is_enabled = true - - configuration { - source { - resource = oci_core_subnet.example_subnet.id - service = "flowlogs" - category = "all" - } - } -} \ No newline at end of file From 1b0a3384a3e041babb894cc9a0a8c8ff4f630c5d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:17:52 +0100 Subject: [PATCH 202/900] fix(queries): remove undocumented README.md from oci_vcn_change_event_rule_missing --- .../README.md | 54 ------------------- 1 file changed, 54 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/README.md diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/README.md b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/README.md deleted file mode 100644 index 5b1d6fa4753..00000000000 --- a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# Regla KICS: Notificación para Cambios en VCN en OCI - -## Descripción General - -Esta regla de KICS para Terraform asegura que exista una regla de eventos (`oci_events_rule`) configurada para monitorizar y generar alertas ante cualquier cambio (creación, actualización o eliminación) en las Redes Virtuales en la Nube (VCN) de la cuenta de OCI. - -Las VCN son el componente fundamental de la red en OCI. Cambios no autorizados pueden tener un impacto severo en la conectividad y la seguridad de los servicios. - -## Lógica de la Regla - -La política verifica la configuración de los recursos `oci_events_rule` buscando los tres tipos de eventos fundamentales: -* `com.oraclecloud.virtualnetwork.createvcn` -* `com.oraclecloud.virtualnetwork.updatevcn` -* `com.oraclecloud.virtualnetwork.deletevcn` - -## Casos de Fallo Detectados - -### Caso 1: Regla Ausente (Missing) -* **Descripción:** No existe ninguna regla en la configuración que monitorice cambios en VCNs. -* **Ubicación:** Bloque `provider "oci"`. - -### Caso 2: Regla Incompleta (Incomplete) -* **Descripción:** Existe una regla pero no incluye los tres eventos requeridos (create, update, delete). -* **Ubicación:** Atributo `condition`. - -### Caso 3: Regla Deshabilitada (Disabled) -* **Descripción:** Existe una regla relevante pero el atributo `is_enabled` es `false`. -* **Ubicación:** Atributo `is_enabled`. - -## Solución - -Asegúrate de incluir una regla habilitada con los eventos correspondientes: - -```terraform -resource "oci_events_rule" "vcn_change_rule" { - display_name = "audit-rule-for-vcn-changes" - compartment_id = var.tenancy_ocid - is_enabled = true - - condition = jsonencode({ - eventType = [ - "com.oraclecloud.virtualnetwork.createvcn", - "com.oraclecloud.virtualnetwork.updatevcn", - "com.oraclecloud.virtualnetwork.deletevcn" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = oci_ons_notification_topic.security_alerts_topic.id - } - } -} \ No newline at end of file From edcd0a2c38e38788d5453a9706599b01b9de8122 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:10 +0100 Subject: [PATCH 203/900] fix(metadata): add experimental flag and Beta prefix to azure_app_service_application_insights_not_configured --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json index 2b34403066f..62be0a6315f 100644 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json @@ -1,6 +1,6 @@ { "id": "721c26ff-776f-4d7a-b151-45447712343b", - "queryName": "App Service Application Insights Not Configured", + "queryName": "Beta - App Service Application Insights Not Configured", "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that Azure App Services and Function Apps are linked to Application Insights for performance monitoring and error tracking.", @@ -9,5 +9,6 @@ "descriptionID": "721c26ff", "cloudProvider": "azure", "cwe": "778", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 7af07f4fcc3b3a35b445b1e575a2263b7a395a93 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:11 +0100 Subject: [PATCH 204/900] fix(metadata): add experimental flag and Beta prefix to azure_app_service_http_logs_disabled --- .../azure/azure_app_service_http_logs_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json index 84ea655c11b..f0a8f890a31 100644 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "72eb3dd8-6892-47d1-9965-a5682de9f4e7", - "queryName": "App Service HTTP Logs Disabled", + "queryName": "Beta - App Service HTTP Logs Disabled", "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that HTTP logs are enabled for Azure App Services. HTTP logs provide records of HTTP requests to the web app, which are crucial for security monitoring and debugging.", @@ -9,5 +9,6 @@ "descriptionID": "72eb3dd8", "cloudProvider": "azure", "cwe": "778", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 19b9f9175da1ce952557a71ba78488dc30570785 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:12 +0100 Subject: [PATCH 205/900] fix(metadata): add experimental flag and Beta prefix to azure_backup_vault_cmk_encryption_disabled --- .../azure_backup_vault_cmk_encryption_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json index bf862b4b77d..14e4d9cb01c 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "bf4474a7-7495-4292-af22-a97c1cc95d2b", - "queryName": "Backup Vault CMK Encryption Disabled", + "queryName": "Beta - Backup Vault CMK Encryption Disabled", "severity": "MEDIUM", "category": "Encryption", "descriptionText": "Ensures that Azure Backup Vaults (Data Protection) are encrypted using Customer-Managed Keys (CMK) stored in Azure Key Vault, instead of platform-managed keys.", @@ -9,5 +9,6 @@ "descriptionID": "bf4474a7", "cloudProvider": "azure", "cwe": "326", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 5506dc22cf09b18391518501100d23ca1c80351e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:14 +0100 Subject: [PATCH 206/900] fix(metadata): add experimental flag and Beta prefix to azure_backup_vault_cross_region_restore_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json index e61bf9b8384..bc233c5d360 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "0117fb32-4265-444d-8030-a0a034958489", - "queryName": "Backup Vault Cross Region Restore Disabled", + "queryName": "Beta - Backup Vault Cross Region Restore Disabled", "severity": "MEDIUM", "category": "Backup", "descriptionText": "Ensures that 'Cross Region Restore' is enabled for Azure Backup Vaults. This allows backup data to be restored in a secondary region, which is critical for disaster recovery scenarios.", @@ -9,5 +9,6 @@ "descriptionID": "0117fb32", "cloudProvider": "azure", "cwe": "668", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From d723023223c4ecaad1e28206ac189a2a9c7aa572 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:15 +0100 Subject: [PATCH 207/900] fix(metadata): add experimental flag and Beta prefix to azure_backup_vault_infrastructure_encryption_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json index fd5744a28c5..cef98b348f8 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "f7bf03d5-ae0e-4b36-aab3-f8d2346a8843", - "queryName": "Backup Vault Infrastructure Encryption Disabled", + "queryName": "Beta - Backup Vault Infrastructure Encryption Disabled", "severity": "MEDIUM", "category": "Encryption", "descriptionText": "Ensures that 'Infrastructure Encryption' is enabled for Azure Backup Vaults. This provides a second layer of encryption (double encryption) for data at rest.", @@ -9,5 +9,6 @@ "descriptionID": "f7bf03d5", "cloudProvider": "azure", "cwe": "312", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From dcf79300825122cbabec1f949cc6816a970e54ca Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:16 +0100 Subject: [PATCH 208/900] fix(metadata): add experimental flag and Beta prefix to azure_bastion_host_missing --- .../terraform/azure/azure_bastion_host_missing/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json b/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json index 682ecf082ad..a73d0e1786d 100644 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "a3e941c5-7708-40d1-943b-7093446ef5e6", - "queryName": "Azure Bastion Host Missing", + "queryName": "Beta - Azure Bastion Host Missing", "severity": "MEDIUM", "category": "Networking and Firewall", "descriptionText": "Ensures that an Azure Bastion Host is present when Virtual Networks are defined. Azure Bastion provides secure and seamless RDP/SSH connectivity to your virtual machines directly from the Azure portal over SSL.", @@ -9,5 +9,6 @@ "descriptionID": "a3e941c5", "cloudProvider": "azure", "cwe": "284", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 77ee6c52fc070d96efc4da693ca3d7d98390a090 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:18 +0100 Subject: [PATCH 209/900] fix(metadata): add experimental flag and Beta prefix to azure_defender_easm_enabled_manual --- .../azure/azure_defender_easm_enabled_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json index 838e3d80dd8..7d9de00665c 100644 --- a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "b9f8511b-bd48-4e9d-8439-94e49e671490", - "queryName": "Microsoft Defender EASM Enabled (Manual)", + "queryName": "Beta - Microsoft Defender EASM Enabled (Manual)", "severity": "INFO", "category": "Observability", "descriptionText": "Ensures that Microsoft Defender External Attack Surface Monitoring (EASM) is enabled. Since EASM cannot be fully configured or verified via standard Terraform resources yet, this rule serves as a manual reminder to verify the service in the Azure Portal.", @@ -9,5 +9,6 @@ "descriptionID": "b9f8511b", "cloudProvider": "azure", "cwe": "778", - "riskScore": "0.0" + "riskScore": "0.0", + "experimental": "true" } \ No newline at end of file From 268d05b7f0b34d5ab26798dfb726c3d8f5d573ca Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:19 +0100 Subject: [PATCH 210/900] fix(metadata): add experimental flag and Beta prefix to azure_elastic_san_public_access_enabled --- .../azure_elastic_san_public_access_enabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json index a18482ec569..cb1888c8c59 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json @@ -1,6 +1,6 @@ { "id": "660863a5-bb45-4907-8afe-d7478177a446", - "queryName": "Elastic SAN Public Network Access Enabled", + "queryName": "Beta - Elastic SAN Public Network Access Enabled", "severity": "HIGH", "category": "Networking and Firewall", "descriptionText": "Ensures that 'public_network_access_enabled' is set to false for Azure Elastic SAN. Disabling public access ensures that the SAN is only accessible via private endpoints within the virtual network.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "284", "descriptionID": "660863a5", - "riskScore": "9.0" + "riskScore": "9.0", + "experimental": "true" } \ No newline at end of file From ab5eda21fc8ddc468ce40180fc0996b03420d5af Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:20 +0100 Subject: [PATCH 211/900] fix(metadata): add experimental flag and Beta prefix to azure_elastic_san_volume_group_cmk_encryption_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json index 9fa8530f2f4..e7a30ea9bf0 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "3b101ad5-3602-4a9e-b6ca-16b7b31b153c", - "queryName": "Elastic SAN Volume Group CMK Encryption Disabled", + "queryName": "Beta - Elastic SAN Volume Group CMK Encryption Disabled", "severity": "MEDIUM", "category": "Encryption", "descriptionText": "Ensures that Azure Elastic SAN Volume Groups are encrypted using Customer-Managed Keys (CMK). Using CMK provides control over key lifecycle and access policies, unlike the default platform-managed keys.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "326", "descriptionID": "3b101ad5", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From b9712066f5e292dbb3e61500b01e59882d092b08 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:21 +0100 Subject: [PATCH 212/900] fix(metadata): add experimental flag and Beta prefix to azure_iot_hub_defender_disabled --- .../azure/azure_iot_hub_defender_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json index e8293373172..5a27576e68d 100644 --- a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "13be738b-78fb-4d0f-a5ed-13e0f36fd385", - "queryName": "Azure IoT Hub Defender Disabled", + "queryName": "Beta - Azure IoT Hub Defender Disabled", "severity": "MEDIUM", "category": "Networking and Firewall", "descriptionText": "Ensures that Microsoft Defender for IoT is enabled for Azure IoT Hubs. Defender for IoT provides threat detection and security posture management for IoT environments.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "693", "descriptionID": "13be738b", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 7d0bc560435231d44a890f96a9d782493cb290bf Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:23 +0100 Subject: [PATCH 213/900] fix(metadata): add experimental flag and Beta prefix to azure_key_vault_key_rotation_disabled --- .../azure_key_vault_key_rotation_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json index 45f4c16aa87..8828f469bcd 100644 --- a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "ca1ffce5-e2f9-4d8a-978e-719d1ed7c7fa", - "queryName": "Key Vault Key Rotation Disabled", + "queryName": "Beta - Key Vault Key Rotation Disabled", "severity": "MEDIUM", "category": "Encryption", "descriptionText": "Ensures that cryptographic keys in Azure Key Vault have an automatic rotation policy configured. Regular key rotation reduces the risk of compromised keys being used for extended periods.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "320", "descriptionID": "ca1ffce5", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 40f3797e225915fefad850128dbc42bc2e561d05 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:24 +0100 Subject: [PATCH 214/900] fix(metadata): add experimental flag and Beta prefix to azure_managed_lustre_cmk_encryption_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json index 3d59a0fd785..64309fc9853 100644 --- a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "7fc653e2-af91-4379-9219-5095caba0ff6", - "queryName": "Azure Managed Lustre Not Encrypted with CMK", + "queryName": "Beta - Azure Managed Lustre Not Encrypted with CMK", "severity": "MEDIUM", "category": "Encryption", "descriptionText": "Ensures that Azure Managed Lustre file systems are encrypted using a Customer-Managed Key (CMK). By default, data is encrypted with platform-managed keys, but CMK provides full control over key rotation and access policies.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "326", "descriptionID": "7fc653e2", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 1e644101a8c36ecad33c785ed4125a54374dc229 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:25 +0100 Subject: [PATCH 215/900] fix(metadata): add experimental flag and Beta prefix to azure_mysql_audit_log_enabled_manual --- .../azure/azure_mysql_audit_log_enabled_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json index c2126b038cc..b787e21ce68 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "8d8ac482-16c2-4eb7-bfab-e2d94d035498", - "queryName": "MySQL Audit Log Enabled (Manual)", + "queryName": "Beta - MySQL Audit Log Enabled (Manual)", "severity": "INFO", "category": "Observability", "descriptionText": "Ensures that the 'audit_log_enabled' server parameter is set to 'ON' for Azure MySQL Database Servers. Since this parameter is often managed via runtime configurations or separate resources, manual verification is required.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "778", "descriptionID": "8d8ac482", - "riskScore": "0.0" + "riskScore": "0.0", + "experimental": "true" } \ No newline at end of file From 8b5b0428b0ad72b4482aa679ff2c24698348ca01 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:26 +0100 Subject: [PATCH 216/900] fix(metadata): add experimental flag and Beta prefix to azure_mysql_audit_log_events_connection_manual --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json index 700d29e52fd..87dac00f41c 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "fe65cd89-28ea-4301-9c50-6dee30553557", - "queryName": "MySQL Audit Log Events Connection (Manual)", + "queryName": "Beta - MySQL Audit Log Events Connection (Manual)", "severity": "INFO", "category": "Observability", "descriptionText": "Ensures that the 'audit_log_events' server parameter includes 'CONNECTION' for Azure MySQL Database Servers. This ensures that successful and failed connection attempts are logged.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "778", "descriptionID": "fe65cd89", - "riskScore": "0.0" + "riskScore": "0.0", + "experimental": "true" } \ No newline at end of file From 3e0fb8a80dd7bc5ed70243b1d1f74e55eef5191b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:28 +0100 Subject: [PATCH 217/900] fix(metadata): add experimental flag and Beta prefix to azure_netapp_account_cmk_encryption_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json index ca65c5c543c..cbe01d8b44d 100644 --- a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "8bed44b5-bcd6-42f4-b7b6-f59fd4edc94a", - "queryName": "NetApp Account CMK Encryption Disabled", + "queryName": "Beta - NetApp Account CMK Encryption Disabled", "severity": "MEDIUM", "category": "Encryption", "descriptionText": "Ensures that Azure NetApp Files accounts are configured to use Customer-Managed Keys (CMK) for encryption, instead of the default platform-managed keys.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "326", "descriptionID": "8bed44b5", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 75574b3ce478cdf35963ce97f0ff00437e48ceaf Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:29 +0100 Subject: [PATCH 218/900] fix(metadata): add experimental flag and Beta prefix to azure_paas_private_endpoint_missing --- .../azure/azure_paas_private_endpoint_missing/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json index 4347d7b85fc..8ee8643c2f9 100644 --- a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "dda11a20-c7c2-43f8-bd52-a4c029ad15e4", - "queryName": "Ensure Private Endpoints Are Used Where Possible", + "queryName": "Beta - Ensure Private Endpoints Are Used Where Possible", "severity": "MEDIUM", "category": "Networking and Firewall", "descriptionText": "Ensures that key Azure PaaS services (Cosmos DB, Storage, SQL, KeyVault, ACR, etc.) are accessed via Private Endpoints. While static analysis cannot resolve IDs across different state files, this rule validates local resource linkages.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "200", "descriptionID": "dda11a20", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From cfa6ccf37dcffc5304958f643a8fae8acaa572e1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:30 +0100 Subject: [PATCH 219/900] fix(metadata): add experimental flag and Beta prefix to azure_production_workload_basic_consumption_sku --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json index 53dd62c61f8..ecb08bcfb3e 100644 --- a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json @@ -1,6 +1,6 @@ { "id": "bd3a6fc3-fadb-472b-b06c-54c7d7645f15", - "queryName": "Production Workload using Basic or Consumption SKU", + "queryName": "Beta - Production Workload using Basic or Consumption SKU", "severity": "LOW", "category": "Resource Management", "descriptionText": "Detects the use of Basic, Free, or Consumption SKUs in Azure resources. These SKUs are often unsuitable for production workloads due to lack of SLAs, VNet integration support, or 'cold start' issues.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "1038", "descriptionID": "bd3a6fc3", - "riskScore": "2.0" + "riskScore": "2.0", + "experimental": "true" } \ No newline at end of file From ea2ffd81200f1c22d9ed372dae97b8a360f0b589 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:32 +0100 Subject: [PATCH 220/900] fix(metadata): add experimental flag and Beta prefix to azure_recovery_services_vault_cmk_encryption_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json index 20eec170567..47d682dbf80 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "9436d439-99f6-4f81-bef2-e7f50d24d453", - "queryName": "Recovery Services Vault CMK Encryption Disabled", + "queryName": "Beta - Recovery Services Vault CMK Encryption Disabled", "severity": "MEDIUM", "category": "Encryption", "descriptionText": "Ensures that Azure Recovery Services Vaults are encrypted using Customer-Managed Keys (CMK) stored in Azure Key Vault. Using CMK provides control over key lifecycle and access policies, unlike the default platform-managed keys.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "326", "descriptionID": "9436d439", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 28bcdf9d905cdd040d211fcb90763cb5b2010cc3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:33 +0100 Subject: [PATCH 221/900] fix(metadata): add experimental flag and Beta prefix to azure_recovery_services_vault_cross_region_restore_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json index 68fd34a1b85..361210786af 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "b7b0bc16-aedc-405e-a27e-cf159c200f1e", - "queryName": "Recovery Services Vault Cross Region Restore Disabled", + "queryName": "Beta - Recovery Services Vault Cross Region Restore Disabled", "severity": "MEDIUM", "category": "Backup", "descriptionText": "Ensures that 'Cross Region Restore' is enabled for Azure Recovery Services Vaults. This feature allows you to restore data in the secondary region, which is essential for business continuity during a primary region disaster.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "668", "descriptionID": "b7b0bc16", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From de6037364b57088b8fd0bd5c68c3094014fead8d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:34 +0100 Subject: [PATCH 222/900] fix(metadata): add experimental flag and Beta prefix to azure_recovery_services_vault_infrastructure_encryption_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json index 66b64c3bd8d..546ee1e4240 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "95e32d9c-77b5-423a-8746-35ab59a85148", - "queryName": "Recovery Services Vault Infrastructure Encryption Disabled", + "queryName": "Beta - Recovery Services Vault Infrastructure Encryption Disabled", "severity": "MEDIUM", "category": "Encryption", "descriptionText": "Ensures that 'Infrastructure Encryption' (Double Encryption) is enabled for Azure Recovery Services Vaults. This provides a second layer of encryption for data at rest using platform-managed keys.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "312", "descriptionID": "95e32d9c", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 09ee7909e5857f5706874c64107084b875c2e250 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:35 +0100 Subject: [PATCH 223/900] fix(metadata): add experimental flag and Beta prefix to azure_sql_server_tde_cmk_disabled --- .../azure/azure_sql_server_tde_cmk_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json index c21b8f8b1e5..6344d1db3e9 100644 --- a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "745e82b3-edf5-4606-a5c2-25d8453e7de6", - "queryName": "SQL Server TDE Not Encrypted with CMK", + "queryName": "Beta - SQL Server TDE Not Encrypted with CMK", "severity": "MEDIUM", "category": "Encryption", "descriptionText": "Ensures that Azure SQL Server Transparent Data Encryption (TDE) is configured with a Customer-Managed Key (CMK) stored in Azure Key Vault, rather than the default Service-Managed Key.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "326", "descriptionID": "745e82b3", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From f838b5c90c9a213bf75cc4416009d5b917f78743 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:37 +0100 Subject: [PATCH 224/900] fix(metadata): add experimental flag and Beta prefix to azure_storage_account_geo_redundancy_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json index 0851f69b599..597807cc04e 100644 --- a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "56c748b8-9ec8-4f3e-84ac-c9a6992e1b20", - "queryName": "Storage Account Geo-Redundancy Disabled", + "queryName": "Beta - Storage Account Geo-Redundancy Disabled", "severity": "MEDIUM", "category": "Availability", "descriptionText": "Ensures that Azure Storage Accounts use Geo-Redundant Storage (GRS, RAGRS, GZRS, or RAGZRS). This is critical for disaster recovery, ensuring data is durable even in the event of a complete regional outage.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "668", "descriptionID": "56c748b8", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From a00883bf9a3bd9d7af8adff4a076fe9bed1cc5b6 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:38 +0100 Subject: [PATCH 225/900] fix(metadata): add experimental flag and Beta prefix to azure_storage_account_infrastructure_encryption_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json index e59db9b4718..18f1080eea7 100644 --- a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "d02793e5-b3b5-4cfa-b379-7a81d5bfe170", - "queryName": "Storage Account Infrastructure Encryption Disabled", + "queryName": "Beta - Storage Account Infrastructure Encryption Disabled", "severity": "MEDIUM", "category": "Encryption", "descriptionText": "Ensures that 'Infrastructure Encryption' is enabled for Azure Storage Accounts. This provides a second layer of encryption (double encryption) for data at rest, protecting against the compromise of any single encryption algorithm or key.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "312", "descriptionID": "d02793e5", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 5c66421f505730a37911c3f7e306749026b40ef1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:39 +0100 Subject: [PATCH 226/900] fix(metadata): add experimental flag and Beta prefix to azure_storage_account_read_only_lock_missing --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json index 29f1171ca19..14b4d2f1819 100644 --- a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "3a716202-a630-4f23-b8ba-2dcbc40e2fa7", - "queryName": "Storage Account ReadOnly Lock Missing", + "queryName": "Beta - Storage Account ReadOnly Lock Missing", "severity": "LOW", "category": "Resource Management", "descriptionText": "Ensures that Azure Storage Accounts have a Resource Manager lock with 'ReadOnly' level applied. This prevents accidental modification or deletion of the storage account configuration.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "400", "descriptionID": "3a716202", - "riskScore": "2.0" + "riskScore": "2.0", + "experimental": "true" } \ No newline at end of file From 825a19f08d6b7d7ca7c6b7f6522d9f92008c75e5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:40 +0100 Subject: [PATCH 227/900] fix(metadata): add experimental flag and Beta prefix to azure_storage_account_versioning_disabled --- .../azure_storage_account_versioning_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json index 69dc2911b0e..55f0443ecd3 100644 --- a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "0f437572-8be4-4e05-9f76-dd266d7ad90b", - "queryName": "Storage Account Blob Versioning Disabled", + "queryName": "Beta - Storage Account Blob Versioning Disabled", "severity": "MEDIUM", "category": "Backup", "descriptionText": "Ensures that 'Versioning' is enabled for Azure Storage Account Blob services. Blob versioning enables automatic retention of previous versions of an object.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "226", "descriptionID": "0f437572", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 062945a9ae37eca70e58e9d10668fcc657ae19d8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:42 +0100 Subject: [PATCH 228/900] fix(metadata): add experimental flag and Beta prefix to azure_storage_blob_logging_disabled --- .../azure/azure_storage_blob_logging_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json index 2512452d5a6..6a571e788e9 100644 --- a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "11fa88c0-2064-48ee-8431-953c7d961c71", - "queryName": "Storage Blob Service Logging Disabled", + "queryName": "Beta - Storage Blob Service Logging Disabled", "severity": "LOW", "category": "Observability", "descriptionText": "Ensures that Storage Logging is enabled for the Blob service for 'Read', 'Write', and 'Delete' requests. This provides an audit trail of operations performed on blobs and containers.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "778", "descriptionID": "11fa88c0", - "riskScore": "2.0" + "riskScore": "2.0", + "experimental": "true" } \ No newline at end of file From 0fdc0fc899053eff829c26596d774274e3aa22e3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:43 +0100 Subject: [PATCH 229/900] fix(metadata): add experimental flag and Beta prefix to azure_storage_container_immutability_not_locked --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json index bacc6fa781e..6b2650cc1ff 100644 --- a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json @@ -1,6 +1,6 @@ { "id": "9b959753-3a9b-41e7-82b2-28bef91e6b53", - "queryName": "Storage Immutability Policy Not Locked", + "queryName": "Beta - Storage Immutability Policy Not Locked", "severity": "MEDIUM", "category": "Access Control", "descriptionText": "Ensures that the Immutability Policy for Azure Storage Containers is set to 'Locked'. An unlocked policy can be removed or modified, failing to provide true WORM (Write Once, Read Many) compliance for business-critical data.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "284", "descriptionID": "9b959753", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From cf61f829f344f24cfefcd0d41578fb51b4f3c707 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:44 +0100 Subject: [PATCH 230/900] fix(metadata): add experimental flag and Beta prefix to azure_storage_critical_data_cmk_manual --- .../azure_storage_critical_data_cmk_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json index 88381703072..78d893e0ddf 100644 --- a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "20fcb3ef-4524-4d45-baa9-60b0eb229beb", - "queryName": "Critical Data Storage CMK (Manual)", + "queryName": "Beta - Critical Data Storage CMK (Manual)", "severity": "INFO", "category": "Encryption", "descriptionText": "Identifies Storage Accounts using default Platform-Managed Keys. If these accounts store business-critical or sensitive data, they must be encrypted using Customer-Managed Keys (CMK). Manual verification of data sensitivity is required.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "312", "descriptionID": "20fcb3ef", - "riskScore": "0.0" + "riskScore": "0.0", + "experimental": "true" } \ No newline at end of file From 830672d7ec07d115dae4b4102218084a6c8338ee Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:45 +0100 Subject: [PATCH 231/900] fix(metadata): add experimental flag and Beta prefix to azure_storage_queue_logging_disabled --- .../azure/azure_storage_queue_logging_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json index ddc7f545aaf..3c3ff8609d9 100644 --- a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "cddbdd74-3736-4aec-ba57-43b4db315bc2", - "queryName": "Storage Queue Service Logging Disabled", + "queryName": "Beta - Storage Queue Service Logging Disabled", "severity": "LOW", "category": "Observability", "descriptionText": "Ensures that Storage Logging is enabled for the Queue service for 'Read', 'Write', and 'Delete' requests. This provides an audit trail of operations performed on the queues.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "778", "descriptionID": "cddbdd74", - "riskScore": "2.0" + "riskScore": "2.0", + "experimental": "true" } \ No newline at end of file From 287af1312da57c37a2f0daba94dacab45be355cc Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:47 +0100 Subject: [PATCH 232/900] fix(metadata): add experimental flag and Beta prefix to azure_storage_table_logging_disabled --- .../azure/azure_storage_table_logging_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json index c92fc2276cd..3fabe299d93 100644 --- a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "0d29e3cf-0033-4ca6-9b97-fa3e6c4d25b8", - "queryName": "Storage Table Service Logging Disabled", + "queryName": "Beta - Storage Table Service Logging Disabled", "severity": "LOW", "category": "Observability", "descriptionText": "Ensures that Storage Logging is enabled for the Table service for 'Read', 'Write', and 'Delete' requests. This provides an audit trail of operations performed on NoSQL tables within the storage account.", @@ -9,5 +9,6 @@ "cloudProvider": "azure", "cwe": "778", "descriptionID": "0d29e3cf", - "riskScore": "2.0" + "riskScore": "2.0", + "experimental": "true" } \ No newline at end of file From ced09ab3637ef7d203c6b139fcbce5845417c58d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:48 +0100 Subject: [PATCH 233/900] fix(metadata): add experimental flag and Beta prefix to gcp_access_approval_disabled --- .../terraform/gcp/gcp_access_approval_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json index c8fd4d884be..79455656962 100644 --- a/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "d7df9989-f87a-45cb-80ea-d4d20e3d4530", - "queryName": "GCP Access Approval Disabled", + "queryName": "Beta - GCP Access Approval Disabled", "severity": "MEDIUM", "category": "Access Control", "descriptionText": "Ensures that Access Approval is enabled for the GCP Project. Access Approval allows you to approve or deny access to your data by Google support and engineering personnel.", @@ -9,5 +9,6 @@ "descriptionID": "d7df9989", "cloudProvider": "gcp", "cwe": "284", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 6abc605a4d9140024a9627131ce2a24179d07037 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:49 +0100 Subject: [PATCH 234/900] fix(metadata): add experimental flag and Beta prefix to gcp_api_key_api_targets_missing --- .../gcp/gcp_api_key_api_targets_missing/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json index 52efef95070..76c5e2bb585 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "8097afd6-ef1a-4a58-b5f8-5d1b70ab4818", - "queryName": "Google API Key API Targets Missing", + "queryName": "Beta - Google API Key API Targets Missing", "severity": "MEDIUM", "category": "Access Control", "descriptionText": "Ensures that Google Cloud API Keys are restricted to specific APIs. By default, an API key can be used to access any API enabled in the project, which increases the blast radius if the key is compromised.", @@ -9,5 +9,6 @@ "descriptionID": "8097afd6", "cloudProvider": "gcp", "cwe": "284", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From b41c95befe7e349183bfd0855dccac3db4f16f59 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:50 +0100 Subject: [PATCH 235/900] fix(metadata): add experimental flag and Beta prefix to gcp_api_key_restrictions_manual --- .../gcp/gcp_api_key_restrictions_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json index 646a76655ad..6baa6fe927c 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "7b3ba800-c190-4b65-ae4d-fa1e5f7bc75e", - "queryName": "Google API Key Restrictions (Manual)", + "queryName": "Beta - Google API Key Restrictions (Manual)", "severity": "INFO", "category": "Access Control", "descriptionText": "Ensures that Google Cloud API Keys are restricted. If restrictions are present, they must be manually verified to ensure they list the correct IPs, websites, or apps.", @@ -9,5 +9,6 @@ "descriptionID": "7b3ba800", "cloudProvider": "gcp", "cwe": "284", - "riskScore": "0.0" + "riskScore": "0.0", + "experimental": "true" } \ No newline at end of file From 62e46c6ee3aa3a352a3619cb3d2f2641a7a6075e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:52 +0100 Subject: [PATCH 236/900] fix(metadata): add experimental flag and Beta prefix to gcp_app_engine_https_enforcement_manual --- .../gcp_app_engine_https_enforcement_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json index d386627ecae..9a4e22f249c 100644 --- a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "52b7bc15-032e-4dd7-b9c3-6dc9698aa131", - "queryName": "App Engine HTTPS Enforcement (Manual)", + "queryName": "Beta - App Engine HTTPS Enforcement (Manual)", "severity": "INFO", "category": "Encryption", "descriptionText": "Ensures that Google App Engine applications enforce HTTPS connections. This is typically configured in 'app.yaml' using 'secure: always' or in Terraform via the 'handlers' block with 'security_level'. Manual verification is often required.", @@ -9,5 +9,6 @@ "descriptionID": "52b7bc15", "cloudProvider": "gcp", "cwe": "319", - "riskScore": "0.0" + "riskScore": "0.0", + "experimental": "true" } \ No newline at end of file From 4350f36ecb7b8ed387b71d664bfebaf777fa9abf Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:53 +0100 Subject: [PATCH 237/900] fix(metadata): add experimental flag and Beta prefix to gcp_compute_logging_service_disabled --- .../gcp/gcp_compute_logging_service_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json index c3eb4755785..4c5ac85ff83 100644 --- a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "ccefc589-0310-45a4-a2b6-d558e629e019", - "queryName": "GCP Compute Logging Service Disabled", + "queryName": "Beta - GCP Compute Logging Service Disabled", "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that the 'google-logging-enabled' metadata flag is set to 'true' for Google Compute Engine instances. This flag configures the instance to send logs to Cloud Logging.", @@ -9,5 +9,6 @@ "descriptionID": "ccefc589", "cloudProvider": "gcp", "cwe": "778", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 7aab9b6a2009cb8c3176475b79bda0ee649f2fb4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:54 +0100 Subject: [PATCH 238/900] fix(metadata): add experimental flag and Beta prefix to gcp_gke_default_service_account_used --- .../gcp/gcp_gke_default_service_account_used/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json index a173a5838bb..b46ce5d7602 100644 --- a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json @@ -1,6 +1,6 @@ { "id": "8ef3f681-6ef1-4bbd-94bb-f9fe6d0626da", - "queryName": "GKE Default Service Account Used", + "queryName": "Beta - GKE Default Service Account Used", "severity": "HIGH", "category": "Access Control", "descriptionText": "Ensures that GKE clusters do not use the default Compute Engine Service Account. The default account has the 'Editor' role, granting nodes excessive write permissions to the project.", @@ -9,5 +9,6 @@ "descriptionID": "8ef3f681", "cloudProvider": "gcp", "cwe": "276", - "riskScore": "9.0" + "riskScore": "9.0", + "experimental": "true" } \ No newline at end of file From 6e520d10ab5370816d269dff2240a1fd4ef50bba Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:55 +0100 Subject: [PATCH 239/900] fix(metadata): add experimental flag and Beta prefix to gcp_gke_image_vulnerability_scanning_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json index 440389df232..eda1632cb93 100644 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "30b5b4bb-a4dd-41b5-9caf-32e9b017a35e", - "queryName": "GKE Image Vulnerability Scanning Disabled", + "queryName": "Beta - GKE Image Vulnerability Scanning Disabled", "severity": "HIGH", "category": "Supply-Chain", "descriptionText": "Ensures that Image Vulnerability Scanning is enabled in GKE clusters via the security posture configuration. This feature automatically scans workloads for known vulnerabilities.", @@ -9,5 +9,6 @@ "descriptionID": "30b5b4bb", "cloudProvider": "gcp", "cwe": "1395", - "riskScore": "9.0" + "riskScore": "9.0", + "experimental": "true" } \ No newline at end of file From c44e694d94ea4563a6851eeabba7fe87ba582c4d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:57 +0100 Subject: [PATCH 240/900] fix(metadata): add experimental flag and Beta prefix to gcp_gke_manual_iam_check --- .../terraform/gcp/gcp_gke_manual_iam_check/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json index 9a4ed430fcb..ea49720a364 100644 --- a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json @@ -1,6 +1,6 @@ { "id": "b29ff836-5b2e-4089-a40c-086426ef3980", - "queryName": "GKE Service Account IAM Review (Manual)", + "queryName": "Beta - GKE Service Account IAM Review (Manual)", "severity": "INFO", "category": "Supply-Chain", "descriptionText": "A custom Service Account is configured for GKE nodes. Manual verification is required to ensure this account has Read-Only access to Container Registries (e.g., 'roles/storage.objectViewer') and not Write access.", @@ -9,5 +9,6 @@ "descriptionID": "b29ff836", "cloudProvider": "gcp", "cwe": "276", - "riskScore": "0.0" + "riskScore": "0.0", + "experimental": "true" } \ No newline at end of file From 5878167f922f512f9a3c568627381af9541d68eb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:21:58 +0100 Subject: [PATCH 241/900] fix(metadata): add experimental flag and Beta prefix to gcp_gke_metadata_server_disabled --- .../gcp/gcp_gke_metadata_server_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json index 3fb6cc664fd..3e41f143bd7 100644 --- a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "e858428b-7650-4a62-a7d4-5b0d4c9afdd6", - "queryName": "GKE Metadata Server Disabled", + "queryName": "Beta - GKE Metadata Server Disabled", "severity": "HIGH", "category": "Access Control", "descriptionText": "Ensures that the GKE Metadata Server is enabled by setting 'workload_metadata_config.mode' to 'GKE_METADATA'. This prevents pods from accessing the sensitive Compute Engine metadata server and node credentials.", @@ -9,5 +9,6 @@ "descriptionID": "e858428b", "cloudProvider": "gcp", "cwe": "284", - "riskScore": "9.0" + "riskScore": "9.0", + "experimental": "true" } \ No newline at end of file From d0b05cd4d243252492f80e30340b0b818fbc452c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:00 +0100 Subject: [PATCH 242/900] fix(metadata): add experimental flag and Beta prefix to gcp_gke_sandbox_disabled --- .../terraform/gcp/gcp_gke_sandbox_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json index 4f9d7325c8b..a66fdd88ddc 100644 --- a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "6c8a93a9-c0c5-4314-8ee6-3bcb3a0dbd70", - "queryName": "GKE Sandbox (gVisor) Disabled", + "queryName": "Beta - GKE Sandbox (gVisor) Disabled", "severity": "LOW", "category": "Insecure Configurations", "descriptionText": "GKE Sandbox (gVisor) provides an extra layer of defense for untrusted workloads. It is not enabled on this Node Pool. Consider enabling it if this pool runs untrusted code (e.g., SaaS user scripts).", @@ -9,5 +9,6 @@ "descriptionID": "6c8a93a9", "cloudProvider": "gcp", "cwe": "1038", - "riskScore": "3.0" + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From d66c7803ecb675191e00113ab6011682fa1f0a11 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:01 +0100 Subject: [PATCH 243/900] fix(metadata): add experimental flag and Beta prefix to gcp_gke_secrets_encryption_cmek_disabled --- .../gcp_gke_secrets_encryption_cmek_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json index fc76dfc2ce3..ca14d3aecfe 100644 --- a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "83d1c89f-e07c-4748-9d96-51a78c49637c", - "queryName": "GKE Secrets Not Encrypted with CMEK", + "queryName": "Beta - GKE Secrets Not Encrypted with CMEK", "severity": "HIGH", "category": "Encryption", "descriptionText": "Ensures that GKE clusters have Application-Layer Secrets Encryption enabled using a Cloud KMS key. This protects sensitive data in etcd with a customer-managed encryption key.", @@ -9,5 +9,6 @@ "descriptionID": "83d1c89f", "cloudProvider": "gcp", "cwe": "312", - "riskScore": "9.0" + "riskScore": "9.0", + "experimental": "true" } \ No newline at end of file From ebe68a665a2c5d2c7bf1dca85fcdbfedaea5c78a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:02 +0100 Subject: [PATCH 244/900] fix(metadata): add experimental flag and Beta prefix to gcp_gke_security_posture_manual --- .../gcp/gcp_gke_security_posture_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json index 5f3543185af..21b2cb79fb2 100644 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "0d688e9b-79a1-4adb-8893-4cae93442ffd", - "queryName": "GKE Security Posture Disabled (Manual)", + "queryName": "Beta - GKE Security Posture Disabled (Manual)", "severity": "INFO", "category": "Observability", "descriptionText": "GKE Security Posture Dashboard provides visibility into the security status of the cluster. It is not explicitly enabled. Verify if the cluster version supports 'security_posture_config' with mode 'BASIC' or 'ENTERPRISE'.", @@ -9,5 +9,6 @@ "descriptionID": "0d688e9b", "cloudProvider": "gcp", "cwe": "1038", - "riskScore": "0.0" + "riskScore": "0.0", + "experimental": "true" } \ No newline at end of file From fb91dbc8e131742308e275f5e3a268d0966cc9f1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:03 +0100 Subject: [PATCH 245/900] fix(metadata): add experimental flag and Beta prefix to gcp_gke_workload_identity_manual --- .../gcp/gcp_gke_workload_identity_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json index 95436764b02..f240462ceff 100644 --- a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "edea054b-6ed2-4be2-bad2-459891848678", - "queryName": "GKE Workload Identity & Dedicated SA (Manual)", + "queryName": "Beta - GKE Workload Identity & Dedicated SA (Manual)", "severity": "INFO", "category": "Access Control", "descriptionText": "Ensures that GKE clusters have Workload Identity enabled. If enabled, manual verification is required to ensure that workloads use dedicated Google Service Accounts (1:1 mapping) rather than shared ones.", @@ -9,5 +9,6 @@ "descriptionID": "edea054b", "cloudProvider": "gcp", "cwe": "284", - "riskScore": "0.0" + "riskScore": "0.0", + "experimental": "true" } \ No newline at end of file From eb1af4ea10955dd3d85302962f297515bf309f7f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:05 +0100 Subject: [PATCH 246/900] fix(metadata): add experimental flag and Beta prefix to gcp_http_load_balancer_logging_disabled --- .../gcp_http_load_balancer_logging_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json index 93ec73c9933..407d3fa2d4c 100644 --- a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "0ef3f3f1-0592-475b-b073-81ac1ac869e2", - "queryName": "GCP HTTP(S) Load Balancer Logging Disabled", + "queryName": "Beta - GCP HTTP(S) Load Balancer Logging Disabled", "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that logging is enabled for Google Compute Backend Services used in HTTP(S) Load Balancers. Access logs are essential for monitoring traffic patterns, latency, and identifying potential security threats.", @@ -9,5 +9,6 @@ "descriptionID": "0ef3f3f1", "cloudProvider": "gcp", "cwe": "778", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 86ee623d2a0e1c3c44d52f3748ce486890af3759 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:06 +0100 Subject: [PATCH 247/900] fix(metadata): add experimental flag and Beta prefix to gcp_iap_backend_service_disabled --- .../gcp/gcp_iap_backend_service_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json index 91026cd1fa1..694b775059c 100644 --- a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "3f1222a9-0161-4fe8-b188-ccabaf7a0ba5", - "queryName": "IAP Disabled on Backend Service", + "queryName": "Beta - IAP Disabled on Backend Service", "severity": "MEDIUM", "category": "Access Control", "descriptionText": "Ensures that Identity-Aware Proxy (IAP) is enabled for Google Compute Backend Services. IAP verifies user identity and context before allowing access to applications.", @@ -9,5 +9,6 @@ "descriptionID": "3f1222a9", "cloudProvider": "gcp", "cwe": "284", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From e80c9378c20c6fd931dada39d178f71d5ff5598d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:07 +0100 Subject: [PATCH 248/900] fix(metadata): add experimental flag and Beta prefix to gcp_sql_postgresql_log_error_verbosity_verbose --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json index 7f93ca0a6ae..fcc80188a28 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json @@ -1,6 +1,6 @@ { "id": "80d98d7b-2f12-4a8c-8cc9-fd17ca19c569", - "queryName": "Cloud SQL PostgreSQL log_error_verbosity is Verbose", + "queryName": "Beta - Cloud SQL PostgreSQL log_error_verbosity is Verbose", "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that the 'log_error_verbosity' flag for Cloud SQL PostgreSQL instances is set to 'default' or 'terse'. Setting it to 'verbose' generates excessive logs containing internal source code details, which can be a security risk.", @@ -9,5 +9,6 @@ "descriptionID": "80d98d7b", "cloudProvider": "gcp", "cwe": "532", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From baf6094465fec9f8bc8896e662039e66255a2e60 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:09 +0100 Subject: [PATCH 249/900] fix(metadata): add experimental flag and Beta prefix to gcp_sql_postgresql_log_statement_improperly_set --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json index 5ab38538ac6..892d75807d9 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json @@ -1,6 +1,6 @@ { "id": "ede2d9e4-d3a6-4751-a89b-561bc9bacbe4", - "queryName": "Cloud SQL PostgreSQL log_statement Improperly Set", + "queryName": "Beta - Cloud SQL PostgreSQL log_statement Improperly Set", "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that the 'log_statement' database flag for Cloud SQL PostgreSQL instances is set to 'ddl', 'mod', or 'all'. The default value is 'none', which disables statement logging and hinders auditing capability.", @@ -9,5 +9,6 @@ "descriptionID": "ede2d9e4", "cloudProvider": "gcp", "cwe": "778", - "riskScore": "5.0" + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 5605ed82d035ca86d801ba7b9c22af4d168c1569 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:10 +0100 Subject: [PATCH 250/900] fix(metadata): add experimental flag and Beta prefix to ibm_activity_tracker_global_events_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json index c73977dba20..b33534c72ab 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "479bbdfd-342a-4121-8844-7387eea26d96", - "queryName": "Activity Tracker for Global Events Disabled", + "queryName": "Beta - Activity Tracker for Global Events Disabled", "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that an IBM Cloud Activity Tracker instance is provisioned to capture IAM and other global account events. For compliance and security, at least one instance must be configured in a region that supports receiving global events.", @@ -9,5 +9,6 @@ "descriptionID": "479bbdfd", "cloudProvider": "ibm", "cwe": "778", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 143cc10633d1198acbd603019e56a9917189572e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:11 +0100 Subject: [PATCH 251/900] fix(metadata): add experimental flag and Beta prefix to ibm_activity_tracker_platform_logs_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json index ba5e52bd52a..89b5f98b13a 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "ccf65fe5-85f2-414d-b68e-b5101bc4bc03", - "queryName": "Activity Tracker Platform Logs Disabled", + "queryName": "Beta - Activity Tracker Platform Logs Disabled", "severity": "HIGH", "category": "Observability", "descriptionText": "Ensures that the IBM Cloud Activity Tracker instance is configured to receive platform logs. Capturing platform management events is critical for security auditing, threat detection, and compliance.", @@ -9,5 +9,6 @@ "descriptionID": "ccf65fe5", "cloudProvider": "ibm", "cwe": "778", - "riskScore": 6.0 + "riskScore": 6.0, + "experimental": "true" } \ No newline at end of file From 7453bb1ab47dae26c10e07a7e73b809c75151229 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:13 +0100 Subject: [PATCH 252/900] fix(metadata): add experimental flag and Beta prefix to ibm_block_storage_customer_encryption_unified --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json index 8e700e56478..652684418ae 100644 --- a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json +++ b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json @@ -1,6 +1,6 @@ { "id": "56cd75da-f919-4350-8b32-1d0e4313e965", - "queryName": "IBM Block Storage Encryption (CMK/BYOK/KYOK) Manual", + "queryName": "Beta - IBM Block Storage Encryption (CMK/BYOK/KYOK) Manual", "severity": "INFO", "category": "Encryption", "descriptionText": "The Block Storage volume uses default provider-managed encryption. It is not configured with 'encryption_key', which is required for Customer Managed Keys (CMK), Bring Your Own Key (BYOK), or Keep Your Own Key (KYOK). Manual verification of the key source is required.", @@ -9,5 +9,6 @@ "descriptionID": "56cd75da", "cloudProvider": "ibm", "cwe": "312", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From a54ccb996d9c21ba056b1f0d951c1fed3ce3d24a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:14 +0100 Subject: [PATCH 253/900] fix(metadata): add experimental flag and Beta prefix to ibm_certificate_manager_auto_renew_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json index a6bbc84bfac..67547ffe99d 100644 --- a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "6797782b-0523-4419-9297-1747e1bf82ab", - "queryName": "Certificate Manager Auto Renew Disabled", + "queryName": "Beta - Certificate Manager Auto Renew Disabled", "severity": "MEDIUM", "category": "Best Practices", "descriptionText": "Ensures that certificates managed by IBM Cloud Certificate Manager are configured to renew automatically before expiration. Disabling auto-renewal can lead to service disruptions and security risks due to expired certificates.", @@ -9,5 +9,6 @@ "descriptionID": "6797782b", "cloudProvider": "ibm", "cwe": "320", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 6c9e003d1c426cfeff2b98c1cf86b38e8f7c312f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:15 +0100 Subject: [PATCH 254/900] fix(metadata): add experimental flag and Beta prefix to ibm_cis_dns_not_proxied_manual --- .../ibm/ibm_cis_dns_not_proxied_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/metadata.json b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/metadata.json index ad4e22f476f..80f3266dee0 100644 --- a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "124e18ee-0b42-474d-8623-185f108fa545", - "queryName": "IBM CIS DNS Record Not Proxied (Manual)", + "queryName": "Beta - IBM CIS DNS Record Not Proxied (Manual)", "severity": "INFO", "category": "Availability", "descriptionText": "The DNS record in IBM Cloud Internet Services (CIS) is not proxied. DDoS protection, WAF, and CDN features are only active when 'proxied' is set to 'true'. Verify if this record points to a web workload that requires DDoS mitigation.", @@ -9,5 +9,6 @@ "descriptionID": "124e18ee", "cloudProvider": "ibm", "cwe": "770", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From cce7da08ff4d0c3c11497ca67d5b54cde113aeee Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:17 +0100 Subject: [PATCH 255/900] fix(metadata): add experimental flag and Beta prefix to ibm_cis_waf_enabled_manual --- .../terraform/ibm/ibm_cis_waf_enabled_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/metadata.json b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/metadata.json index 585bbc82fcb..9738ed595dd 100644 --- a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "1e0c94f5-6178-4601-b33e-a86d8aa20bd6", - "queryName": "IBM CIS WAF Not Enabled (Manual)", + "queryName": "Beta - IBM CIS WAF Not Enabled (Manual)", "severity": "INFO", "category": "Networking and Firewall", "descriptionText": "The Web Application Firewall (WAF) is not explicitly set to 'on' in the IBM Cloud Internet Services (CIS) domain settings. WAF is a critical compensatory control for protecting web workloads. Manual verification is required to ensure WAF is enabled and rules are properly tuned.", @@ -9,5 +9,6 @@ "descriptionID": "1e0c94f5", "cloudProvider": "ibm", "cwe": "1021", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From 4be90e060652fe23b2d047a5ae1b6910d6242619 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:18 +0100 Subject: [PATCH 256/900] fix(metadata): add experimental flag and Beta prefix to ibm_cloudant_cmk_encryption_manual --- .../ibm/ibm_cloudant_cmk_encryption_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/metadata.json b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/metadata.json index 4cf780d188f..c0cf5257209 100644 --- a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "601ca2bb-20a9-4113-83b3-866a3d1a2a67", - "queryName": "IBM Cloudant Encryption with CMK (Manual)", + "queryName": "Beta - IBM Cloudant Encryption with CMK (Manual)", "severity": "INFO", "category": "Encryption", "descriptionText": "The IBM Cloudant instance (provisioned via 'ibm_resource_instance') does not appear to have Customer Managed Encryption configured. To enable CMK/BYOK, the 'parameters' block must contain the Key Protect root key CRN (usually 'key_protect_key'). Manual verification is required.", @@ -9,5 +9,6 @@ "descriptionID": "601ca2bb", "cloudProvider": "ibm", "cwe": "312", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From c876cc98d7ca618f67b3a72d552b689b9bdcbf48 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:19 +0100 Subject: [PATCH 257/900] fix(metadata): add experimental flag and Beta prefix to ibm_container_cluster_entitlement_check --- .../ibm_container_cluster_entitlement_check/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/metadata.json b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/metadata.json index 95b89185446..61b79e76258 100644 --- a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/metadata.json +++ b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/metadata.json @@ -1,6 +1,6 @@ { "id": "d2fc37af-3cd9-4830-b8a0-a3eda8fba0ed", - "queryName": "IBM Cluster Entitlement Key Missing (Automated)", + "queryName": "Beta - IBM Cluster Entitlement Key Missing (Automated)", "severity": "INFO", "category": "Supply-Chain", "descriptionText": "The IBM Cloud Kubernetes Service cluster does not have an 'entitlement' key configured. This argument automates the creation of image pull secrets for the IBM Entitled Registry. If using IBM Cloud Paks or entitled software, this should be defined to ensure secure image pull access.", @@ -9,5 +9,6 @@ "descriptionID": "d2fc37af", "cloudProvider": "ibm", "cwe": "284", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From 3606172960ff513e78edd335baf0c8f5aefec377 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:21 +0100 Subject: [PATCH 258/900] fix(metadata): add experimental flag and Beta prefix to ibm_container_registry_va_alerts_missing --- .../ibm_container_registry_va_alerts_missing/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json index 83b00164611..efbe7647d8a 100644 --- a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json +++ b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "92440d0d-889c-49c5-a0e6-13c5f326b872", - "queryName": "IBM Container Registry VA Alerts Missing (Automated)", + "queryName": "Beta - IBM Container Registry VA Alerts Missing (Automated)", "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that notifications are enabled for the Vulnerability Advisor (VA) in IBM Cloud Container Registry. The resource 'ibm_container_va_notification' allows configuring alerts (email, webhook) for new vulnerabilities found in container images.", @@ -9,5 +9,6 @@ "descriptionID": "92440d0d", "cloudProvider": "ibm", "cwe": "778", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 4c793ec5d4efd8c0af3d24b8557c62243096b1c9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:22 +0100 Subject: [PATCH 259/900] fix(metadata): add experimental flag and Beta prefix to ibm_cos_bucket_customer_encryption_unified --- .../ibm_cos_bucket_customer_encryption_unified/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json index ae022f1e3c9..55ca607347d 100644 --- a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json +++ b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json @@ -1,6 +1,6 @@ { "id": "8f65bf01-e9e9-4dd6-82b1-67051c2f073d", - "queryName": "IBM COS Bucket Encryption (CMK/BYOK/KYOK) Manual", + "queryName": "Beta - IBM COS Bucket Encryption (CMK/BYOK/KYOK) Manual", "severity": "INFO", "category": "Encryption", "descriptionText": "The Cloud Object Storage bucket relies on default provider-managed encryption. It is not configured with 'key_protect', which is required for Customer Managed Keys (CMK), Bring Your Own Key (BYOK), or Keep Your Own Key (KYOK). Manual verification is required to determine the specific encryption requirement.", @@ -9,5 +9,6 @@ "descriptionID": "8f65bf01", "cloudProvider": "ibm", "cwe": "312", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From 73ee5d15277a91fff9a1c5cf02c2c4d800c156c7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:23 +0100 Subject: [PATCH 260/900] fix(metadata): add experimental flag and Beta prefix to ibm_database_cmk_encryption_manual --- .../ibm/ibm_database_cmk_encryption_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/metadata.json b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/metadata.json index da99104d27e..d90015ea0e6 100644 --- a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "c973475c-4797-42b1-8cee-4038c050283e", - "queryName": "IBM Cloud Database Without CMK (Manual)", + "queryName": "Beta - IBM Cloud Database Without CMK (Manual)", "severity": "INFO", "category": "Encryption", "descriptionText": "The IBM Cloud Database instance is not configured with a Customer Managed Key (CMK). It relies on default provider-managed encryption. Verify if the data sensitivity requires Bring Your Own Key (BYOK) or Keep Your Own Key (KYOK) via the 'key_protect_key' argument.", @@ -9,5 +9,6 @@ "descriptionID": "c973475c", "cloudProvider": "ibm", "cwe": "312", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From e8c9e68b15e08bf50b309919067c9a950c845bcc Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:25 +0100 Subject: [PATCH 261/900] fix(metadata): add experimental flag and Beta prefix to ibm_iam_account_ip_restrictions_manual --- .../ibm/ibm_iam_account_ip_restrictions_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/metadata.json index e0cb5215b3a..4fd8870a814 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "61d76d70-0021-45c7-855d-c8c5c3116877", - "queryName": "IBM Account IP Restrictions (Manual)", + "queryName": "Beta - IBM Account IP Restrictions (Manual)", "severity": "INFO", "category": "Networking and Firewall", "descriptionText": "The account global settings do not enforce IP address restrictions. The 'allowed_ip_addresses' attribute should be configured to restrict login access (including the account owner) to trusted networks only.", @@ -9,5 +9,6 @@ "descriptionID": "61d76d70", "cloudProvider": "ibm", "cwe": "284", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From 0499250bb5fad025670462252f38bc2906d623ad Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:26 +0100 Subject: [PATCH 262/900] fix(metadata): add experimental flag and Beta prefix to ibm_iam_account_mfa_disabled --- .../terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json index 760dee34438..b5ba4cd7d10 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "ebaef99e-4add-440e-8270-caeb718e7c93", - "queryName": "Account Level MFA Is Not Enforced", + "queryName": "Beta - Account Level MFA Is Not Enforced", "severity": "HIGH", "category": "Access Control", "descriptionText": "Enforces Multi-Factor Authentication (MFA) at the account level. Requiring MFA is a fundamental security practice to prevent unauthorized access resulting from compromised credentials.", @@ -9,5 +9,6 @@ "descriptionID": "ebaef99e", "cloudProvider": "ibm", "cwe": "308", - "riskScore": 9.0 + "riskScore": 9.0, + "experimental": "true" } \ No newline at end of file From 11322451cf712911a7d927ee915925eea8749407 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:27 +0100 Subject: [PATCH 263/900] fix(metadata): add experimental flag and Beta prefix to ibm_iam_api_key_unused_manual --- .../ibm/ibm_iam_api_key_unused_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json index d60818a7755..f3f5bfb44a9 100644 --- a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "a2b88f1a-038f-4898-a7c1-61eb2aa41143", - "queryName": "IBM Cloud API Keys Unused for 180 Days (Manual)", + "queryName": "Beta - IBM Cloud API Keys Unused for 180 Days (Manual)", "severity": "INFO", "category": "Observability", "descriptionText": "Terraform cannot detect if an IBM Cloud IAM API Key is unused. This rule flags the creation of API Keys to remind the auditor to establish an automated process to detect and disable keys unused for 180 days.", @@ -9,5 +9,6 @@ "descriptionID": "a2b88f1a", "cloudProvider": "ibm", "cwe": "798", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From a06c7eca339ba71cbdac4d986644c30e76a00821 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:28 +0100 Subject: [PATCH 264/900] fix(metadata): add experimental flag and Beta prefix to ibm_iam_owner_api_key_manual --- .../terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json index fc7fccf9f7c..de01413b4ed 100644 --- a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "dae483b9-d462-49d1-993c-4d398cad281e", - "queryName": "IBM Owner Account API Key (Manual)", + "queryName": "Beta - IBM Owner Account API Key (Manual)", "severity": "INFO", "category": "Access Control", "descriptionText": "The account owner should not have an associated API Key. Using owner credentials implies unlimited privileges and poses a catastrophic risk if compromised. Verify that this API Key does not belong to the Account Owner.", @@ -9,5 +9,6 @@ "descriptionID": "dae483b9", "cloudProvider": "ibm", "cwe": "269", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From c6b3050113a51757957082df995be391559f15ac Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:30 +0100 Subject: [PATCH 265/900] fix(metadata): add experimental flag and Beta prefix to ibm_iam_policy_assigned_to_user_manual --- .../ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json index f97974148c0..73d14879ab9 100644 --- a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "d08b8443-aa59-4099-9523-5cfc6bee1d4a", - "queryName": "IBM IAM Policies Attached to Users (Manual)", + "queryName": "Beta - IBM IAM Policies Attached to Users (Manual)", "severity": "INFO", "category": "Access Control", "descriptionText": "Detects usage of 'ibm_iam_user_policy'. Access policies should be assigned to Access Groups ('ibm_iam_access_group_policy') rather than directly to users to ensure scalable and manageable IAM governance.", @@ -9,5 +9,6 @@ "descriptionID": "d08b8443", "cloudProvider": "ibm", "cwe": "284", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From 1c753bc847c370175305f2020214f95cd313f567 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:31 +0100 Subject: [PATCH 266/900] fix(metadata): add experimental flag and Beta prefix to ibm_iam_restrict_apikey_creation_manual --- .../ibm_iam_restrict_apikey_creation_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json index f9e4db1b9a1..71a1b328bc2 100644 --- a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "30640fc8-88be-4053-882c-55fd0febaf3f", - "queryName": "Restrict API Key & Service ID Creation (Manual)", + "queryName": "Beta - Restrict API Key & Service ID Creation (Manual)", "severity": "INFO", "category": "Access Control", "descriptionText": "CIS controls recommend restricting the creation of API Keys and Service IDs to privileged users only. Review IAM policies to ensure 'Editor' or 'Administrator' roles (or custom roles with creation actions) are not granted broadly.", @@ -9,5 +9,6 @@ "descriptionID": "30640fc8", "cloudProvider": "ibm", "cwe": "276", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From 55359061efbc66fcc24382be6f81b4eb3c7106d7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:32 +0100 Subject: [PATCH 267/900] fix(metadata): add experimental flag and Beta prefix to ibm_iam_session_expiration_too_long --- .../ibm/ibm_iam_session_expiration_too_long/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json index ec40a2f20b8..7f668e1132c 100644 --- a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json @@ -1,6 +1,6 @@ { "id": "3d6db2d6-fa2d-41df-a783-d3dee76f717f", - "queryName": "IBM Account Session Expiration Too Long", + "queryName": "Beta - IBM Account Session Expiration Too Long", "severity": "MEDIUM", "category": "Access Control", "descriptionText": "Ensures that the IBM Cloud account session expiration is configured to a secure limit (e.g., 3600 seconds / 1 hour). Long session timeouts increase the risk of session hijacking.", @@ -9,5 +9,6 @@ "descriptionID": "3d6db2d6", "cloudProvider": "ibm", "cwe": "613", - "riskScore": 5.0 + "riskScore": 5.0, + "experimental": "true" } \ No newline at end of file From 3649ab3ce6b6e37536680b6f94cf106c6c5571fc Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:33 +0100 Subject: [PATCH 268/900] fix(metadata): add experimental flag and Beta prefix to ibm_iks_cluster_logging_disabled --- .../ibm/ibm_iks_cluster_logging_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json index 926044c4d00..11e1c58e2da 100644 --- a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "e55a0224-47b8-41a8-8cc1-8c8581e13a8d", - "queryName": "IKS Cluster Logging Disabled", + "queryName": "Beta - IKS Cluster Logging Disabled", "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that every IBM Cloud Kubernetes Service (IKS) cluster has an associated logging service configuration. Centralized logging is essential for troubleshooting applications, monitoring cluster activity, and performing security analysis.", @@ -9,5 +9,6 @@ "descriptionID": "e55a0224", "cloudProvider": "ibm", "cwe": "778", - "riskScore": 5.0 + "riskScore": 5.0, + "experimental": "true" } \ No newline at end of file From ec6a1e531eab11d2501dfcaf3d0bc86704e2c6da Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:34 +0100 Subject: [PATCH 269/900] fix(metadata): add experimental flag and Beta prefix to ibm_iks_cluster_monitoring_disabled --- .../ibm/ibm_iks_cluster_monitoring_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json index d647f353b8b..f3ca90151be 100644 --- a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "51bac252-399d-49d0-bfa5-0bd52194fed9", - "queryName": "IKS Cluster Monitoring Disabled", + "queryName": "Beta - IKS Cluster Monitoring Disabled", "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that every IBM Cloud Kubernetes Service (IKS) cluster has an associated monitoring service configuration. Monitoring is essential for observing cluster health, performance, and resource utilization.", @@ -9,5 +9,6 @@ "descriptionID": "51bac252", "cloudProvider": "ibm", "cwe": "778", - "riskScore": 5.0 + "riskScore": 5.0, + "experimental": "true" } \ No newline at end of file From 75b880dedf8a15c03b3cb1760870aac7ad37550a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:36 +0100 Subject: [PATCH 270/900] fix(metadata): add experimental flag and Beta prefix to ibm_instance_os_disk_encryption_manual --- .../ibm/ibm_instance_os_disk_encryption_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/metadata.json b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/metadata.json index 72bf60cf62c..4c484059d05 100644 --- a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/metadata.json +++ b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "86f1560c-74cb-48a3-ad5a-7da25cab4d03", - "queryName": "IBM Instance OS Disk Encryption (Manual)", + "queryName": "Beta - IBM Instance OS Disk Encryption (Manual)", "severity": "INFO", "category": "Encryption", "descriptionText": "The Virtual Server Instance boot volume (OS Disk) relies on default provider-managed encryption. It is not configured with 'boot_volume.encryption', which is required for Customer Managed Keys (CMK), BYOK, or KYOK.", @@ -9,5 +9,6 @@ "descriptionID": "86f1560c", "cloudProvider": "ibm", "cwe": "312", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From f25bdaae0fc6a240d5c76f3d9de5f3b7305826d7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:37 +0100 Subject: [PATCH 271/900] fix(metadata): add experimental flag and Beta prefix to ibm_kms_key_rotation_disabled --- .../ibm/ibm_kms_key_rotation_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json index 13264914a47..74ed670cbf1 100644 --- a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "cdaf415c-d1b9-4d15-8e6f-e27165b49d55", - "queryName": "KMS Key Rotation Disabled", + "queryName": "Beta - KMS Key Rotation Disabled", "severity": "HIGH", "category": "Encryption", "descriptionText": "Ensures that cryptographic keys in IBM Key Protect have an automated rotation policy enabled. Rotating keys periodically limits the amount of data exposed if a single key is compromised.", @@ -9,5 +9,6 @@ "descriptionID": "cdaf415c", "cloudProvider": "ibm", "cwe": "320", - "riskScore": 9.0 + "riskScore": 9.0, + "experimental": "true" } \ No newline at end of file From 9873ffb38150852875543a79f0d7cef77ead6845 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:38 +0100 Subject: [PATCH 272/900] fix(metadata): add experimental flag and Beta prefix to ibm_logdna_archiving_disabled --- .../ibm/ibm_logdna_archiving_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json index 6176da424f6..62b7804a9af 100644 --- a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "54c5b041-1902-4e19-b414-5473f1b349d2", - "queryName": "LogDNA Archiving Is Disabled", + "queryName": "Beta - LogDNA Archiving Is Disabled", "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that every IBM LogDNA instance has archiving configured through an 'ibm_logdna_archive' resource. Archiving is critical for long-term log retention, compliance, and forensic analysis.", @@ -9,5 +9,6 @@ "descriptionID": "54c5b041", "cloudProvider": "ibm", "cwe": "223", - "riskScore": 5.0 + "riskScore": 5.0, + "experimental": "true" } \ No newline at end of file From 4c0cbc6d13f999d83fe2e0b8e4785ce61e99202b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:40 +0100 Subject: [PATCH 273/900] fix(metadata): add experimental flag and Beta prefix to ibm_logdna_view_without_alert --- .../ibm/ibm_logdna_view_without_alert/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json index 962f9d1ea8b..e3aba5ae6b7 100644 --- a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json +++ b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json @@ -1,6 +1,6 @@ { "id": "a5107e68-028f-4b4d-9fc0-f23e3b73e448", - "queryName": "LogDNA View Without Alert", + "queryName": "Beta - LogDNA View Without Alert", "severity": "LOW", "category": "Observability", "descriptionText": "Ensures that every IBM LogDNA custom view ('ibm_logdna_view') has at least one associated alert ('ibm_logdna_alert'). Views are created to filter critical events, and without an alert, notifications for these events will not be sent.", @@ -9,5 +9,6 @@ "descriptionID": "a5107e68", "cloudProvider": "ibm", "cwe": "778", - "riskScore": 1.0 + "riskScore": 1.0, + "experimental": "true" } \ No newline at end of file From aa0d6569d3f895e5da5c4939f375bf133ea104a1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:41 +0100 Subject: [PATCH 274/900] fix(metadata): add experimental flag and Beta prefix to oci_cloud_guard_problem_event_rule_missing --- .../oci_cloud_guard_problem_event_rule_missing/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json index 1f069ec2587..cadf393c214 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "3ce366ab-e97d-4040-aa67-5a08dad595fb", - "queryName": "Event Rule for Cloud Guard Problems is Missing", + "queryName": "Beta - Event Rule for Cloud Guard Problems is Missing", "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that an OCI event rule is configured to create notifications for problems detected by Cloud Guard. Without a notification rule, critical security findings from Cloud Guard may go unnoticed, delaying response to potential threats.", @@ -9,5 +9,6 @@ "descriptionID": "3ce366ab", "cloudProvider": "oci", "cwe": "778", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 15f882de2a94cefb082ce6cf20dce1735dc6d9f9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:42 +0100 Subject: [PATCH 275/900] fix(metadata): add experimental flag and Beta prefix to oci_cloud_guard_root_compartment_disabled --- .../oci_cloud_guard_root_compartment_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json index 60537e2b884..70dad5bcde8 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "3e784705-b3c6-4197-9a04-0b751b1a83d8", - "queryName": "Cloud Guard Not Enabled at Root Compartment", + "queryName": "Beta - Cloud Guard Not Enabled at Root Compartment", "severity": "HIGH", "category": "Security Services", "descriptionText": "Ensures that OCI Cloud Guard is enabled at the tenancy's root compartment. Cloud Guard is a cloud-native security posture management service that helps monitor, identify, and maintain a strong security posture on Oracle Cloud.", @@ -9,5 +9,6 @@ "descriptionID": "3e784705", "cloudProvider": "oci", "cwe": "16", - "riskScore": 6.0 + "riskScore": 6.0, + "experimental": "true" } \ No newline at end of file From 9322fe5db1b178b9c622cd1ccede5648ef53b034 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:44 +0100 Subject: [PATCH 276/900] fix(metadata): add experimental flag and Beta prefix to oci_compute_legacy_metadata_enabled --- .../oci/oci_compute_legacy_metadata_enabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json index 9a3c40335f8..8abe6f94857 100644 --- a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json @@ -1,6 +1,6 @@ { "id": "96b464dc-a778-4b99-8634-c9eb9bdecf89", - "queryName": "Compute Instance Legacy Metadata Enabled", + "queryName": "Beta - Compute Instance Legacy Metadata Enabled", "severity": "MEDIUM", "category": "Insecure Configurations", "descriptionText": "Ensures that OCI Compute Instances have legacy metadata service endpoints (IMDSv1) disabled. Enforcing the use of IMDSv2 is a security best practice to mitigate Server-Side Request Forgery (SSRF) vulnerabilities.", @@ -9,5 +9,6 @@ "descriptionID": "96b464dc", "cloudProvider": "oci", "cwe": "918", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 87d9ab1246bde626aabe808213fed3f6f91cc753 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:45 +0100 Subject: [PATCH 277/900] fix(metadata): add experimental flag and Beta prefix to oci_compute_secure_boot_disabled --- .../oci/oci_compute_secure_boot_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json index 597764d82b9..359f0601df4 100644 --- a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "1f24d72d-c8be-403f-92b8-84ed910fe96e", - "queryName": "Compute Instance Secure Boot Disabled", + "queryName": "Beta - Compute Instance Secure Boot Disabled", "severity": "MEDIUM", "category": "Insecure Configurations", "descriptionText": "Ensures that OCI Compute Instances have Secure Boot enabled. Secure Boot is a feature of UEFI firmware that helps prevent unauthorized boot loaders and operating systems from loading during the startup process, protecting against rootkits and boot-level malware.", @@ -9,5 +9,6 @@ "descriptionID": "1f24d72d", "cloudProvider": "oci", "cwe": "427", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 9dc49dac1647768fdca518fec247f91890f98198 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:46 +0100 Subject: [PATCH 278/900] fix(metadata): add experimental flag and Beta prefix to oci_default_tags_not_defined --- .../terraform/oci/oci_default_tags_not_defined/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json b/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json index e228ba1593c..9848e4526b9 100644 --- a/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json +++ b/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json @@ -1,6 +1,6 @@ { "id": "4c294256-f477-41d5-8c7f-f31c9e48092e", - "queryName": "Default Tags Not Defined", + "queryName": "Beta - Default Tags Not Defined", "severity": "LOW", "category": "Best Practices", "descriptionText": "Ensures that a default tagging policy is defined using the 'oci_identity_tag_default' resource. Default tags are crucial for governance as they ensure all resources within a compartment are automatically tagged for cost tracking, automation, and access control.", @@ -9,5 +9,6 @@ "descriptionID": "4c294256", "cloudProvider": "oci", "cwe": "16", - "riskScore": 1.0 + "riskScore": 1.0, + "experimental": "true" } \ No newline at end of file From f0ea7b64df9158a68ec21ae20c00a564eeb21011 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:47 +0100 Subject: [PATCH 279/900] fix(metadata): add experimental flag and Beta prefix to oci_iam_group_change_event_rule_missing --- .../oci_iam_group_change_event_rule_missing/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json index a7579bc602b..f538a2942f5 100644 --- a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "3f6ba6dd-fa6d-45b4-8b27-120b7ebb4d0f", - "queryName": "Event Rule for IAM Group Changes is Missing", + "queryName": "Beta - Event Rule for IAM Group Changes is Missing", "severity": "MEDIUM", "category": "Access Control", "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to IAM groups. Auditing the creation, modification, and deletion of user groups is a critical security measure to detect unauthorized privilege escalation or tampering with access controls.", @@ -9,5 +9,6 @@ "descriptionID": "3f6ba6dd", "cloudProvider": "oci", "cwe": "778", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 32098d2a6e2c6ad3857fd3659ba84355699827ec Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:49 +0100 Subject: [PATCH 280/900] fix(metadata): add experimental flag and Beta prefix to oci_iam_password_expiration_manual --- .../oci/oci_iam_password_expiration_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/metadata.json b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/metadata.json index e71bdce5403..8f632fd7863 100644 --- a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "7f47496b-8cdc-4476-9161-6c58038ef920", - "queryName": "OCI IAM Password Expiration (365 days)", + "queryName": "Beta - OCI IAM Password Expiration (365 days)", "severity": "INFO", "category": "Identity and Access Management", "descriptionText": "CIS Benchmark recommends that passwords expire within 365 days. Verify 'password_expires_after' is set to 365 or less in 'oci_identity_domains_password_policy'. Legacy policies require manual verification.", @@ -9,5 +9,6 @@ "descriptionID": "7f47496b", "cloudProvider": "oci", "cwe": "261", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From fd4e8d8b66c92ebf9fa45663847ac34bb3e89456 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:50 +0100 Subject: [PATCH 281/900] fix(metadata): add experimental flag and Beta prefix to oci_iam_password_policy_length --- .../oci/oci_iam_password_policy_length/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json b/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json index 58a657110f4..0bf9213d405 100644 --- a/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json @@ -1,6 +1,6 @@ { "id": "ef7a0923-a4e6-4aec-921b-1b4e45463fb6", - "queryName": "OCI IAM Password Minimum Length", + "queryName": "Beta - OCI IAM Password Minimum Length", "severity": "MEDIUM", "category": "Identity and Access Management", "descriptionText": "The IAM password policy allows passwords shorter than 14 characters. According to CIS Benchmarks, the 'minimum_password_length' in 'oci_identity_authentication_policy' should be set to 14 or greater.", @@ -9,5 +9,6 @@ "descriptionID": "ef7a0923", "cloudProvider": "oci", "cwe": "521", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 5462e479b0dcc6ff7a3f67416f469ec6cf1baba5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:51 +0100 Subject: [PATCH 282/900] fix(metadata): add experimental flag and Beta prefix to oci_iam_password_reuse_manual --- .../oci/oci_iam_password_reuse_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/metadata.json b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/metadata.json index 0112949bc71..0e8c8c6fde2 100644 --- a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "fc42ff43-3c72-41d1-b5fb-3beebd4efe15", - "queryName": "OCI IAM Password Reuse Prevention (Manual)", + "queryName": "Beta - OCI IAM Password Reuse Prevention (Manual)", "severity": "INFO", "category": "Identity and Access Management", "descriptionText": "CIS Benchmark recommends preventing password reuse for at least the last 24 passwords. Check 'num_passwords_in_history' in 'oci_identity_domains_password_policy'. For legacy 'oci_identity_authentication_policy', this requires manual console verification.", @@ -9,5 +9,6 @@ "descriptionID": "fc42ff43", "cloudProvider": "oci", "cwe": "261", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From 5c3b6b263f9d9f739694aff309a2e9f8808e88c7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:53 +0100 Subject: [PATCH 283/900] fix(metadata): add experimental flag and Beta prefix to oci_iam_policy_change_event_rule_missing --- .../oci_iam_policy_change_event_rule_missing/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json index b3c738001cb..160bb0057f8 100644 --- a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "a151d9a0-d626-447f-beab-11d53aeb0f2b", - "queryName": "Event Rule for IAM Policy Changes is Missing", + "queryName": "Beta - Event Rule for IAM Policy Changes is Missing", "severity": "HIGH", "category": "Access Control", "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to IAM policies. Auditing the creation, modification, and deletion of IAM policies is a critical security measure to detect unauthorized changes to permissions within the tenancy.", @@ -9,5 +9,6 @@ "descriptionID": "a151d9a0", "cloudProvider": "oci", "cwe": "778", - "riskScore": 4.0 + "riskScore": 4.0, + "experimental": "true" } \ No newline at end of file From a3d93adc62908170c44d96dea4e64bec8be08886 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:54 +0100 Subject: [PATCH 284/900] fix(metadata): add experimental flag and Beta prefix to oci_iam_service_admins_manual --- .../oci/oci_iam_service_admins_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_service_admins_manual/metadata.json b/assets/queries/terraform/oci/oci_iam_service_admins_manual/metadata.json index d555d9db3b4..72cf95d1be8 100644 --- a/assets/queries/terraform/oci/oci_iam_service_admins_manual/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_service_admins_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "0401f017-91ee-4019-842a-f940d08b22aa", - "queryName": "OCI Service Level Admins (Manual)", + "queryName": "Beta - OCI Service Level Admins (Manual)", "severity": "INFO", "category": "Identity and Access Management", "descriptionText": "CIS controls recommend creating specific Service Level Administrators (e.g., Network Admin, Storage Admin) rather than relying solely on the default Tenancy Administrator. Review this policy to ensure it delegates 'manage' permissions for specific resource families to appropriate groups, implementing Least Privilege.", @@ -9,5 +9,6 @@ "cloudProvider": "oci", "cwe": "276", "descriptionID": "0401f017", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From 78526276635617f9532f4c9c4e9a7eaedeb311c4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:55 +0100 Subject: [PATCH 285/900] fix(metadata): add experimental flag and Beta prefix to oci_iam_user_change_event_rule_missing --- .../oci/oci_iam_user_change_event_rule_missing/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json index 8bc995bedbd..463e6e831de 100644 --- a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "b1405757-feb9-4218-b685-ff53775ddf48", - "queryName": "Event Rule for IAM User Changes is Missing", + "queryName": "Beta - Event Rule for IAM User Changes is Missing", "severity": "HIGH", "category": "Access Control", "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to IAM users. Auditing the full lifecycle of user accounts (creation, modification, deletion, enable/disable) is a critical security measure to detect unauthorized account creation or privilege changes.", @@ -9,5 +9,6 @@ "descriptionID": "b1405757", "cloudProvider": "oci", "cwe": "778", - "riskScore": 6.0 + "riskScore": 6.0, + "experimental": "true" } \ No newline at end of file From 1c699291a1b9f1e23e1413c0d0e2e6078f521cd4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:56 +0100 Subject: [PATCH 286/900] fix(metadata): add experimental flag and Beta prefix to oci_idp_change_event_rule_missing --- .../oci/oci_idp_change_event_rule_missing/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json index 5b2f34a58f8..2b666efa371 100644 --- a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "0a077b15-dc77-4490-810b-4e34f1b55500", - "queryName": "Event Rule for Identity Provider Changes is Missing", + "queryName": "Beta - Event Rule for Identity Provider Changes is Missing", "severity": "MEDIUM", "category": "Access Control", "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Identity Providers. Monitoring these changes is critical for detecting potentially malicious activity, such as the addition of an unauthorized external identity provider.", @@ -9,5 +9,6 @@ "descriptionID": "0a077b15", "cloudProvider": "oci", "cwe": "778", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 0102caedf3be8d4e50aa6d9d3282398030e03eb1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:58 +0100 Subject: [PATCH 287/900] fix(metadata): add experimental flag and Beta prefix to oci_idp_group_mapping_change_event_rule_missing --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json index f846ac3c86c..077810fbad5 100644 --- a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "1f106aa1-a994-4a11-afbc-109f31947d6a", - "queryName": "Event Rule for IdP Group Mapping Changes is Missing", + "queryName": "Beta - Event Rule for IdP Group Mapping Changes is Missing", "severity": "MEDIUM", "category": "Access Control", "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Identity Provider (IdP) group mappings. Auditing these changes is vital for detecting unauthorized modifications to user group permissions.", @@ -9,5 +9,6 @@ "descriptionID": "1f106aa1", "cloudProvider": "oci", "cwe": "778", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 0bfc273d8ebab70b70ef97b974bf1c4e2a23c553 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:22:59 +0100 Subject: [PATCH 288/900] fix(metadata): add experimental flag and Beta prefix to oci_instance_transit_encryption --- .../oci/oci_instance_transit_encryption/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json b/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json index a5caa03b244..edf93c76dbd 100644 --- a/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json @@ -1,6 +1,6 @@ { "id": "c29ef8f7-33bc-4788-9085-3a561c91f7d1", - "queryName": "OCI Instance In-Transit Encryption Disabled", + "queryName": "Beta - OCI Instance In-Transit Encryption Disabled", "severity": "MEDIUM", "category": "Encryption", "descriptionText": "Compute instances should have in-transit encryption enabled for data moving between the instance and block storage. This is configured via 'is_pv_encryption_in_transit_enabled' in the 'launch_options' block.", @@ -9,5 +9,6 @@ "descriptionID": "c29ef8f7", "cloudProvider": "oci", "cwe": "311", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 24b8fa554dd168b8156d321ed7f703cccb35572d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:00 +0100 Subject: [PATCH 289/900] fix(metadata): add experimental flag and Beta prefix to oci_local_user_authentication_event_rule_missing --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json index e8ebe356558..feef0d4cbcf 100644 --- a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "e0c61731-a692-44d8-bbf2-8279985a4e41", - "queryName": "Event Rule for Local User Authentication is Missing", + "queryName": "Beta - Event Rule for Local User Authentication is Missing", "severity": "HIGH", "category": "Access Control", "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on authentication events from local IAM users. Auditing local user logins is a critical security measure to detect unauthorized access attempts and compromised credentials.", @@ -9,5 +9,6 @@ "descriptionID": "e0c61731", "cloudProvider": "oci", "cwe": "778", - "riskScore": 6.0 + "riskScore": 6.0, + "experimental": "true" } \ No newline at end of file From d96865456fd7aa9db042a0e6c94201bfde198f9c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:02 +0100 Subject: [PATCH 290/900] fix(metadata): add experimental flag and Beta prefix to oci_network_gateway_change_event_rule_missing --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json index 41c8e0f60c3..f9bfda34c12 100644 --- a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "e3ade454-28a1-4a0c-9905-b73e82a648c0", - "queryName": "Event Rule for Network Gateway Changes is Missing", + "queryName": "Beta - Event Rule for Network Gateway Changes is Missing", "severity": "MEDIUM", "category": "Networking and Firewall", "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to all types of Network Gateways (Internet, NAT, Service, DRG, etc.). Auditing gateway changes is crucial for detecting unauthorized modifications to network ingress/egress points.", @@ -9,5 +9,6 @@ "descriptionID": "e3ade454", "cloudProvider": "oci", "cwe": "778", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 84e020eaa0e927783d6c2448da0ef6a51c76a48c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:03 +0100 Subject: [PATCH 291/900] fix(metadata): add experimental flag and Beta prefix to oci_notification_topic_without_subscription --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json index 39d7c4161d3..efcddeb3468 100644 --- a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json @@ -1,6 +1,6 @@ { "id": "8e61709a-7ba2-4d51-a8ef-796a45e7c82c", - "queryName": "Notification Topic Without Subscription", + "queryName": "Beta - Notification Topic Without Subscription", "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that OCI notification topics have at least one active subscription to deliver alerts. A topic without a subscription receives messages but does not send them to any destination, rendering monitoring alerts ineffective.", @@ -9,5 +9,6 @@ "descriptionID": "8e61709a", "cloudProvider": "oci", "cwe": "778", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 00f1d049d48b0594afb4d9dd5f647cd379f16e0e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:04 +0100 Subject: [PATCH 292/900] fix(metadata): add experimental flag and Beta prefix to oci_nsg_change_event_rule_missing --- .../oci/oci_nsg_change_event_rule_missing/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json index 34f43cdb6bc..6fae1ae4d0b 100644 --- a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "a1b080a7-8d58-4018-a14d-17beb72f5cef", - "queryName": "Event Rule for NSG Changes is Missing", + "queryName": "Beta - Event Rule for NSG Changes is Missing", "severity": "MEDIUM", "category": "Networking and Firewall", "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Network Security Groups (NSGs). Auditing changes to NSGs is critical for detecting unauthorized modifications to network micro-segmentation rules that could expose services.", @@ -9,5 +9,6 @@ "descriptionID": "a1b080a7", "cloudProvider": "oci", "cwe": "778", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From ccd6ece41412b2360e45a18c153690c7987420f3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:06 +0100 Subject: [PATCH 293/900] fix(metadata): add experimental flag and Beta prefix to oci_objectstorage_bucket_logging_enabled --- .../oci_objectstorage_bucket_logging_enabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json index b3185a237c1..65e63531975 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json @@ -1,6 +1,6 @@ { "id": "5ecf7b51-8c4b-4911-9d59-1f7f6b9a2143", - "queryName": "Object Storage Bucket Logging Disabled", + "queryName": "Beta - Object Storage Bucket Logging Disabled", "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that OCI Object Storage buckets have object event emission enabled, which is crucial for write-level logging and security auditing.", @@ -9,5 +9,6 @@ "descriptionID": "5ecf7b51", "cloudProvider": "oci", "cwe": "223", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 3144ce361ea91952da6adca68a361c1297b7ad43 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:07 +0100 Subject: [PATCH 294/900] fix(metadata): add experimental flag and Beta prefix to oci_objectstorage_bucket_versioning_disabled --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json index d23f886b3cf..51421402e47 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "72b1c53c-619e-4e0a-937a-9af24cae69df", - "queryName": "Object Storage Bucket Versioning Disabled", + "queryName": "Beta - Object Storage Bucket Versioning Disabled", "severity": "MEDIUM", "category": "Data Security", "descriptionText": "Ensures that OCI Object Storage buckets have versioning enabled. Versioning protects against accidental deletion or overwriting of objects by keeping a history of all object versions.", @@ -9,5 +9,6 @@ "descriptionID": "72b1c53c", "cloudProvider": "oci", "cwe": "668", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From d7d3c41249195eb601265fb33fc4a03abe019919 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:08 +0100 Subject: [PATCH 295/900] fix(metadata): add experimental flag and Beta prefix to oci_resource_created_in_root_compartment --- .../oci_resource_created_in_root_compartment/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json index 43b4c4ff5ad..db1c83524d3 100644 --- a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json +++ b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json @@ -1,6 +1,6 @@ { "id": "eb205044-d89b-40ac-9846-2e5993e091ab", - "queryName": "Resource Created In Root Compartment", + "queryName": "Beta - Resource Created In Root Compartment", "severity": "HIGH", "category": "Best Practices", "descriptionText": "Ensures that resources are not created directly in the root compartment (tenancy). Following the principle of least privilege and separation of concerns, resources should be organized into dedicated child compartments.", @@ -9,5 +9,6 @@ "descriptionID": "eb205044", "cloudProvider": "oci", "cwe": "284", - "riskScore": 6.0 + "riskScore": 6.0, + "experimental": "true" } \ No newline at end of file From 60f347b074cbf52c999f32543d2a6c82580ebce4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:10 +0100 Subject: [PATCH 296/900] fix(metadata): add experimental flag and Beta prefix to oci_route_table_change_event_rule_missing --- .../oci_route_table_change_event_rule_missing/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json index 19cc9e370ab..080eb902f0b 100644 --- a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "b3af1ce8-5711-4304-b1db-17b658629df2", - "queryName": "Event Rule for Route Table Changes is Missing", + "queryName": "Beta - Event Rule for Route Table Changes is Missing", "severity": "MEDIUM", "category": "Networking and Firewall", "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Route Tables. Auditing changes to route tables is critical for detecting unauthorized network path modifications that could lead to traffic interception or service disruption.", @@ -9,5 +9,6 @@ "descriptionID": "b3af1ce8", "cloudProvider": "oci", "cwe": "778", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 95693424e5d53d5cd4e46709c58038a05688e742 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:11 +0100 Subject: [PATCH 297/900] fix(metadata): add experimental flag and Beta prefix to oci_security_list_change_event_rule_missing --- .../metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json index 9582da7f342..b9f61de2141 100644 --- a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "a5dfa109-1f7d-4077-8d10-41247bfcf922", - "queryName": "Event Rule for Security List Changes is Missing", + "queryName": "Beta - Event Rule for Security List Changes is Missing", "severity": "MEDIUM", "category": "Networking and Firewall", "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Security Lists. Auditing changes to these network ACLs is critical for detecting unauthorized modifications that could expose services to unintended traffic.", @@ -9,5 +9,6 @@ "descriptionID": "a5dfa109", "cloudProvider": "oci", "cwe": "778", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From a4b58d7ae13f932106881b285486a3473ca73108 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:12 +0100 Subject: [PATCH 298/900] fix(metadata): add experimental flag and Beta prefix to oci_storage_admin_no_delete_manual --- .../oci/oci_storage_admin_no_delete_manual/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/metadata.json b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/metadata.json index 67d76ec4ced..e065cd7cada 100644 --- a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/metadata.json +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/metadata.json @@ -1,6 +1,6 @@ { "id": "8cd7b5db-800b-4c93-949b-bc215d63f7c3", - "queryName": "OCI Storage Admin with Delete Privileges (Manual)", + "queryName": "Beta - OCI Storage Admin with Delete Privileges (Manual)", "severity": "INFO", "category": "Identity and Access Management", "descriptionText": "Storage service-level admins should ideally not have 'DELETE' permissions to prevent accidental or malicious data loss. The verb 'manage' includes DELETE permissions by default. Verify if a condition 'where request.permission != DELETE' is applied or if the 'manage' verb is necessary.", @@ -9,5 +9,6 @@ "descriptionID": "8cd7b5db", "cloudProvider": "oci", "cwe": "269", - "riskScore": 0.0 + "riskScore": 0.0, + "experimental": "true" } \ No newline at end of file From 6b81f8c26731bd86672c0eec7da08ade11f55c72 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:14 +0100 Subject: [PATCH 299/900] fix(metadata): add experimental flag and Beta prefix to oci_storage_cmk_encryption_unified --- .../oci/oci_storage_cmk_encryption_unified/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json index a35c5bab743..9849bf1dba5 100644 --- a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json +++ b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json @@ -1,6 +1,6 @@ { "id": "cb72ae80-1b5a-407e-9f5b-86ddd64df644", - "queryName": "OCI Storage Resources Without CMK", + "queryName": "Beta - OCI Storage Resources Without CMK", "severity": "MEDIUM", "category": "Encryption", "descriptionText": "Storage resources (Object Storage, Block Volumes, Boot Volumes, File Storage) are using default Oracle-managed encryption keys. To satisfy strict compliance requirements, they should be encrypted with a Customer Managed Key (CMK) by defining the 'kms_key_id' attribute.", @@ -9,5 +9,6 @@ "descriptionID": "cb72ae80", "cloudProvider": "oci", "cwe": "312", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 41573a0cae2e49d09509ba585fc60b52c6e4ac43 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:15 +0100 Subject: [PATCH 300/900] fix(metadata): add experimental flag and Beta prefix to oci_subnet_flow_logging_disabled --- .../oci/oci_subnet_flow_logging_disabled/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json index 16a25033e7a..a23b9fd88ab 100644 --- a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json @@ -1,6 +1,6 @@ { "id": "30d3bb83-f6aa-4302-a647-c404f12f8b8a", - "queryName": "VCN Subnet Without Flow Log", + "queryName": "Beta - VCN Subnet Without Flow Log", "severity": "HIGH", "category": "Observability", "descriptionText": "VCN Subnet should have flow logging enabled to monitor traffic, as per CIS v3.0.0 recommendation 4.13.", @@ -9,5 +9,6 @@ "descriptionID": "30d3bb83", "cloudProvider": "oci", "cwe": "778", - "riskScore": 6.0 + "riskScore": 6.0, + "experimental": "true" } \ No newline at end of file From 32f4b55b8b26b9a2f8525f1f35579146f4be71e1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:16 +0100 Subject: [PATCH 301/900] fix(metadata): add experimental flag and Beta prefix to oci_vcn_change_event_rule_missing --- .../oci/oci_vcn_change_event_rule_missing/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json index 0c669cbabf4..dc73dd6c9c0 100644 --- a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json @@ -1,6 +1,6 @@ { "id": "419bb431-bf37-4e5d-bda6-af3750e808e4", - "queryName": "Event Rule for VCN Changes is Missing", + "queryName": "Beta - Event Rule for VCN Changes is Missing", "severity": "MEDIUM", "category": "Networking and Firewall", "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Virtual Cloud Networks (VCNs). Auditing the creation, modification, and deletion of VCNs is important for detecting unauthorized network changes that could impact security posture.", @@ -9,5 +9,6 @@ "descriptionID": "419bb431", "cloudProvider": "oci", "cwe": "778", - "riskScore": 3.0 + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From d84e91af4927137f29c2138c4ce225d65b447819 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:36 +0100 Subject: [PATCH 302/900] fix(tests): update queryName to Beta prefix in azure_app_service_application_insights_not_configured --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive_expected_result.json index 42119a5fba2..6ef4443546d 100644 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "App Service Application Insights Not Configured", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "App Service Application Insights Not Configured", - "severity": "MEDIUM", - "line": 7, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - App Service Application Insights Not Configured", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - App Service Application Insights Not Configured", + "severity": "MEDIUM", + "line": 7, + "fileName": "positive2.tf" + } +] From 615c66683948cf1309a395d89ef7dc2326c8595e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:37 +0100 Subject: [PATCH 303/900] fix(tests): update queryName to Beta prefix in azure_app_service_http_logs_disabled --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive_expected_result.json index 2b9ba210834..ac98db21878 100644 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "App Service HTTP Logs Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "App Service HTTP Logs Disabled", - "severity": "MEDIUM", - "line": 7, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - App Service HTTP Logs Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - App Service HTTP Logs Disabled", + "severity": "MEDIUM", + "line": 7, + "fileName": "positive2.tf" + } +] From eab4b6d81f792ad27f028d14b8dae3d660bdf179 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:39 +0100 Subject: [PATCH 304/900] fix(tests): update queryName to Beta prefix in azure_backup_vault_cmk_encryption_disabled --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive_expected_result.json index 6ef8a5a5a91..f8491137b15 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "Backup Vault CMK Encryption Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Backup Vault CMK Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] From 45d8715d85d8eb4d95fdd07bc339bec98fd7d667 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:40 +0100 Subject: [PATCH 305/900] fix(tests): update queryName to Beta prefix in azure_backup_vault_cross_region_restore_disabled --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive_expected_result.json index bcfd1994ee5..2479f5831c8 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Backup Vault Cross Region Restore Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Backup Vault Cross Region Restore Disabled", - "severity": "MEDIUM", - "line": 8, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Backup Vault Cross Region Restore Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Backup Vault Cross Region Restore Disabled", + "severity": "MEDIUM", + "line": 8, + "fileName": "positive2.tf" + } +] From e1bad01b302551f8b2ca32422d1259af13f6f82d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:41 +0100 Subject: [PATCH 306/900] fix(tests): update queryName to Beta prefix in azure_backup_vault_infrastructure_encryption_disabled --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive_expected_result.json index 4979de3f2ab..cdf3aead85f 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "Backup Vault Infrastructure Encryption Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Backup Vault Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] From 7fc2e635005083634073dd2cc332e2ae50a04206 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:42 +0100 Subject: [PATCH 307/900] fix(tests): update queryName to Beta prefix in azure_bastion_host_missing --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive_expected_result.json index 865959bff36..9d20dd2ef7a 100644 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "Azure Bastion Host Missing", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Azure Bastion Host Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] From 86f4823bd3ad503474487071fb587b609d758bb9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:44 +0100 Subject: [PATCH 308/900] fix(tests): update queryName to Beta prefix in azure_defender_easm_enabled_manual --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive_expected_result.json index ccef5c4313c..e3d5fa7f0bf 100644 --- a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "Microsoft Defender EASM Enabled (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Microsoft Defender EASM Enabled (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + } +] From f98b10a3af211715f39755033bd670267ba5c1fc Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:45 +0100 Subject: [PATCH 309/900] fix(tests): update queryName to Beta prefix in azure_elastic_san_public_access_enabled --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive_expected_result.json index dbe5fa31bfe..e782d3b36aa 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "Elastic SAN Public Network Access Enabled", - "severity": "HIGH", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Elastic SAN Public Network Access Enabled", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + } +] From 086c8e227bb36322f8611d614446f0871e9befaf Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:46 +0100 Subject: [PATCH 310/900] fix(tests): update queryName to Beta prefix in azure_elastic_san_volume_group_cmk_encryption_disabled --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json index 32f203345b4..97e9d3cbcfd 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Elastic SAN Volume Group CMK Encryption Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Elastic SAN Volume Group CMK Encryption Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Elastic SAN Volume Group CMK Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Elastic SAN Volume Group CMK Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive2.tf" + } +] From 372b99033a6f53ba104fad73a0cbd56a581ddd02 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:48 +0100 Subject: [PATCH 311/900] fix(tests): update queryName to Beta prefix in azure_iot_hub_defender_disabled --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive_expected_result.json index 64e4501aad7..c4952e6c3a5 100644 --- a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "Azure IoT Hub Defender Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Azure IoT Hub Defender Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] From ece5d5a2b221460a53c58e814515a29aa8d356f4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:49 +0100 Subject: [PATCH 312/900] fix(tests): update queryName to Beta prefix in azure_key_vault_key_rotation_disabled --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/positive_expected_result.json index e3ffd2c068e..fe87fbfef1e 100644 --- a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "Key Vault Key Rotation Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Key Vault Key Rotation Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] From 48e7e36f4924257d64aed1b11c02b12e49e8dbb0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:50 +0100 Subject: [PATCH 313/900] fix(tests): update queryName to Beta prefix in azure_managed_lustre_cmk_encryption_disabled --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/positive_expected_result.json index 256fed25d3e..b3d1a6397b5 100644 --- a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "Azure Managed Lustre Not Encrypted with CMK", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Azure Managed Lustre Not Encrypted with CMK", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] From 411018fc1977a01ac900f4e1085cd82fc22b468f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:51 +0100 Subject: [PATCH 314/900] fix(tests): update queryName to Beta prefix in azure_mysql_audit_log_enabled_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive_expected_result.json index 17539402a93..831f402432a 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "MySQL Audit Log Enabled (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "MySQL Audit Log Enabled (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - MySQL Audit Log Enabled (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - MySQL Audit Log Enabled (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + } +] From 698879fe92c5d0a54d0d12ac7bc4b111d1813829 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:53 +0100 Subject: [PATCH 315/900] fix(tests): update queryName to Beta prefix in azure_mysql_audit_log_events_connection_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json index 2b4dd87ee4a..0c4e71fe8ea 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "MySQL Audit Log Events Connection (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "MySQL Audit Log Events Connection (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - MySQL Audit Log Events Connection (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - MySQL Audit Log Events Connection (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + } +] From 759e7723829d309aa0f660889ce1c2a48a7d9586 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:54 +0100 Subject: [PATCH 316/900] fix(tests): update queryName to Beta prefix in azure_netapp_account_cmk_encryption_disabled --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive_expected_result.json index 40945f981f6..60253e45ad4 100644 --- a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "NetApp Account CMK Encryption Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - NetApp Account CMK Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] From dce4817515eb1a10ca3f4465bebc175c1eb10ce3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:55 +0100 Subject: [PATCH 317/900] fix(tests): update queryName to Beta prefix in azure_paas_private_endpoint_missing --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive_expected_result.json index e92aa602481..d00852245b5 100644 --- a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Ensure Private Endpoints Are Used Where Possible", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Ensure Private Endpoints Are Used Where Possible", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Ensure Private Endpoints Are Used Where Possible", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Ensure Private Endpoints Are Used Where Possible", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive2.tf" + } +] From b3d6ed02adafd7aad147e03629b2c365571a8db0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:56 +0100 Subject: [PATCH 318/900] fix(tests): update queryName to Beta prefix in azure_production_workload_basic_consumption_sku --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive_expected_result.json index 0e52a4b0071..a04beb0966f 100644 --- a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Production Workload using Basic or Consumption SKU", - "severity": "LOW", - "line": 6, - "fileName": "positive1.tf" - }, - { - "queryName": "Production Workload using Basic or Consumption SKU", - "severity": "LOW", - "line": 7, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Production Workload using Basic or Consumption SKU", + "severity": "LOW", + "line": 6, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Production Workload using Basic or Consumption SKU", + "severity": "LOW", + "line": 7, + "fileName": "positive2.tf" + } +] From 8dcb4a36025509c340a70bdbd181f13b310ab0ce Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:58 +0100 Subject: [PATCH 319/900] fix(tests): update queryName to Beta prefix in azure_recovery_services_vault_cmk_encryption_disabled --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive_expected_result.json index ff3d72812a2..1e8483eb9e0 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "Recovery Services Vault CMK Encryption Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Recovery Services Vault CMK Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] From fde0ac62cb246b9643367bce29ceca45804c247e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:23:59 +0100 Subject: [PATCH 320/900] fix(tests): update queryName to Beta prefix in azure_recovery_services_vault_cross_region_restore_disabled --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive_expected_result.json index ad96799ed4d..c36f1fcf6ef 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Recovery Services Vault Cross Region Restore Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Recovery Services Vault Cross Region Restore Disabled", - "severity": "MEDIUM", - "line": 7, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Recovery Services Vault Cross Region Restore Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Recovery Services Vault Cross Region Restore Disabled", + "severity": "MEDIUM", + "line": 7, + "fileName": "positive2.tf" + } +] From 216439c8ed90b81312e6c8be1b6339998c4f2d4e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:00 +0100 Subject: [PATCH 321/900] fix(tests): update queryName to Beta prefix in azure_recovery_services_vault_infrastructure_encryption_disabled --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive_expected_result.json index 098d8633fae..001591f57a8 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Recovery Services Vault Infrastructure Encryption Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Recovery Services Vault Infrastructure Encryption Disabled", - "severity": "MEDIUM", - "line": 9, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Recovery Services Vault Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Recovery Services Vault Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "line": 9, + "fileName": "positive2.tf" + } +] From 0f7dca06e1814d7c48e4d0a9858ed2fc4deac4d3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:02 +0100 Subject: [PATCH 322/900] fix(tests): update queryName to Beta prefix in azure_sql_server_tde_cmk_disabled --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive_expected_result.json index c6f6f5d4124..cdd71bd7acf 100644 --- a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "SQL Server TDE Not Encrypted with CMK", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - SQL Server TDE Not Encrypted with CMK", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] From 4ada1c5b09dacb9ad841a7a51bda12d306ee1f16 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:03 +0100 Subject: [PATCH 323/900] fix(tests): update queryName to Beta prefix in azure_storage_account_geo_redundancy_disabled --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/positive_expected_result.json index a6c97123f83..40e6c325211 100644 --- a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "Storage Account Geo-Redundancy Disabled", - "severity": "MEDIUM", - "line": 6, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Storage Account Geo-Redundancy Disabled", + "severity": "MEDIUM", + "line": 6, + "fileName": "positive1.tf" + } +] From 0854647de302c4707791202d2abc1a0f21b608e7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:04 +0100 Subject: [PATCH 324/900] fix(tests): update queryName to Beta prefix in azure_storage_account_infrastructure_encryption_disabled --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive_expected_result.json index 4c58ec8ff3a..21705fb2395 100644 --- a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Storage Account Infrastructure Encryption Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Storage Account Infrastructure Encryption Disabled", - "severity": "MEDIUM", - "line": 7, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Storage Account Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Storage Account Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "line": 7, + "fileName": "positive2.tf" + } +] From a427cb5425239ba3a0d040875ff9b917e36f2e4c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:06 +0100 Subject: [PATCH 325/900] fix(tests): update queryName to Beta prefix in azure_storage_account_read_only_lock_missing --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive_expected_result.json index 97fd3418dd5..77f6226307f 100644 --- a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Storage Account ReadOnly Lock Missing", - "severity": "LOW", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Storage Account ReadOnly Lock Missing", - "severity": "LOW", - "line": 12, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Storage Account ReadOnly Lock Missing", + "severity": "LOW", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Storage Account ReadOnly Lock Missing", + "severity": "LOW", + "line": 12, + "fileName": "positive2.tf" + } +] From 72d862129fdbf691868c6e491bf5de1063a1fb33 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:07 +0100 Subject: [PATCH 326/900] fix(tests): update queryName to Beta prefix in azure_storage_account_versioning_disabled --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive_expected_result.json index 19db728ea31..bd93877ba51 100644 --- a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Storage Account Blob Versioning Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Storage Account Blob Versioning Disabled", - "severity": "MEDIUM", - "line": 8, - "fileName": "positive2.tf" - }, - { - "queryName": "Storage Account Blob Versioning Disabled", - "severity": "MEDIUM", - "line": 9, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Storage Account Blob Versioning Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Storage Account Blob Versioning Disabled", + "severity": "MEDIUM", + "line": 8, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Storage Account Blob Versioning Disabled", + "severity": "MEDIUM", + "line": 9, + "fileName": "positive3.tf" + } +] From 5bc34b3cc1422319e0a4fc8cf1a3365fe4fe42e9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:09 +0100 Subject: [PATCH 327/900] fix(tests): update queryName to Beta prefix in azure_storage_blob_logging_disabled --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive_expected_result.json index 77b0bab39ad..9f8f5b883cd 100644 --- a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Storage Blob Service Logging Disabled", - "severity": "LOW", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Storage Blob Service Logging Disabled", - "severity": "LOW", - "line": 1, - "fileName": "positive2.tf" - }, - { - "queryName": "Storage Blob Service Logging Disabled", - "severity": "LOW", - "line": 6, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Storage Blob Service Logging Disabled", + "severity": "LOW", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Storage Blob Service Logging Disabled", + "severity": "LOW", + "line": 1, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Storage Blob Service Logging Disabled", + "severity": "LOW", + "line": 6, + "fileName": "positive3.tf" + } +] From bb46d104e4243f3c417887721158bba6e76be21c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:10 +0100 Subject: [PATCH 328/900] fix(tests): update queryName to Beta prefix in azure_storage_container_immutability_not_locked --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive_expected_result.json index 3559388eb05..a79dc0b8fb3 100644 --- a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Storage Immutability Policy Not Locked", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Storage Immutability Policy Not Locked", - "severity": "MEDIUM", - "line": 4, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Storage Immutability Policy Not Locked", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Storage Immutability Policy Not Locked", + "severity": "MEDIUM", + "line": 4, + "fileName": "positive2.tf" + } +] From 1ea2309ae3b79170de8a0a17d6086f685adafd13 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:11 +0100 Subject: [PATCH 329/900] fix(tests): update queryName to Beta prefix in azure_storage_critical_data_cmk_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive_expected_result.json index 3c78101dd5c..d556848e2e8 100644 --- a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Critical Data Storage CMK (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Critical Data Storage CMK (Manual)", - "severity": "INFO", - "line": 8, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Critical Data Storage CMK (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Critical Data Storage CMK (Manual)", + "severity": "INFO", + "line": 8, + "fileName": "positive2.tf" + } +] From ded437e9c32bcce2f1f2d68bfa73fe00a72b5008 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:12 +0100 Subject: [PATCH 330/900] fix(tests): update queryName to Beta prefix in azure_storage_queue_logging_disabled --- .../test/positive_expected_result.json | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive_expected_result.json index 253c872e665..05277735a7c 100644 --- a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive_expected_result.json @@ -1,26 +1,26 @@ -[ - { - "queryName": "Storage Queue Service Logging Disabled", - "severity": "LOW", - "line": 8, - "fileName": "positive1.tf" - }, - { - "queryName": "Storage Queue Service Logging Disabled", - "severity": "LOW", - "line": 9, - "fileName": "positive2.tf" - }, - { - "queryName": "Storage Queue Service Logging Disabled", - "severity": "LOW", - "line": 1, - "fileName": "positive3.tf" - }, - { - "queryName": "Storage Queue Service Logging Disabled", - "severity": "LOW", - "line": 3, - "fileName": "positive4.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Storage Queue Service Logging Disabled", + "severity": "LOW", + "line": 8, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Storage Queue Service Logging Disabled", + "severity": "LOW", + "line": 9, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Storage Queue Service Logging Disabled", + "severity": "LOW", + "line": 1, + "fileName": "positive3.tf" + }, + { + "queryName": "Beta - Storage Queue Service Logging Disabled", + "severity": "LOW", + "line": 3, + "fileName": "positive4.tf" + } +] From 425b7b38a9d8a051412995f8e9795ac583c79e14 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:14 +0100 Subject: [PATCH 331/900] fix(tests): update queryName to Beta prefix in azure_storage_table_logging_disabled --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive_expected_result.json index b853eeccf65..39044a3903f 100644 --- a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Storage Table Service Logging Disabled", - "severity": "LOW", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Storage Table Service Logging Disabled", - "severity": "LOW", - "line": 1, - "fileName": "positive2.tf" - }, - { - "queryName": "Storage Table Service Logging Disabled", - "severity": "LOW", - "line": 15, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Storage Table Service Logging Disabled", + "severity": "LOW", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Storage Table Service Logging Disabled", + "severity": "LOW", + "line": 1, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Storage Table Service Logging Disabled", + "severity": "LOW", + "line": 15, + "fileName": "positive3.tf" + } +] From aceb209e6c4abf9ec7ef72d2093bcb8deec47985 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:15 +0100 Subject: [PATCH 332/900] fix(tests): update queryName to Beta prefix in gcp_access_approval_disabled --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive_expected_result.json index 6099b814b74..d3b7f99ab01 100644 --- a/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "GCP Access Approval Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "GCP Access Approval Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - GCP Access Approval Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - GCP Access Approval Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive2.tf" + } +] From f194f92a8fd3a402435f656072d2a3d58b91ce84 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:17 +0100 Subject: [PATCH 333/900] fix(tests): update queryName to Beta prefix in gcp_api_key_api_targets_missing --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive_expected_result.json index 7afa3f11d84..079973a7a80 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Google API Key API Targets Missing", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Google API Key API Targets Missing", - "severity": "MEDIUM", - "line": 5, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Google API Key API Targets Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Google API Key API Targets Missing", + "severity": "MEDIUM", + "line": 5, + "fileName": "positive2.tf" + } +] From 620f26413b78eaa2f52a438dbd636950ae1de9a7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:18 +0100 Subject: [PATCH 334/900] fix(tests): update queryName to Beta prefix in gcp_api_key_restrictions_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive_expected_result.json index a6e13f9849c..ddbc995c264 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Google API Key Restrictions (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Google API Key Restrictions (Manual)", - "severity": "INFO", - "line": 5, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Google API Key Restrictions (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Google API Key Restrictions (Manual)", + "severity": "INFO", + "line": 5, + "fileName": "positive2.tf" + } +] From b12aa1d06625012c3ac98c7e2594b0299fc03437 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:20 +0100 Subject: [PATCH 335/900] fix(tests): update queryName to Beta prefix in gcp_app_engine_https_enforcement_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive_expected_result.json index d4dae947860..28ef3d2aa89 100644 --- a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "App Engine HTTPS Enforcement (Manual)", - "severity": "INFO", - "line": 6, - "fileName": "positive1.tf" - }, - { - "queryName": "App Engine HTTPS Enforcement (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - App Engine HTTPS Enforcement (Manual)", + "severity": "INFO", + "line": 6, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - App Engine HTTPS Enforcement (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + } +] From 030f8d29ec68506e957e40f462818464e08c9633 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:21 +0100 Subject: [PATCH 336/900] fix(tests): update queryName to Beta prefix in gcp_compute_logging_service_disabled --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive_expected_result.json index a8f97e871bb..cca496d1ebb 100644 --- a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "GCP Compute Logging Service Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "GCP Compute Logging Service Disabled", - "severity": "MEDIUM", - "line": 3, - "fileName": "positive2.tf" - }, - { - "queryName": "GCP Compute Logging Service Disabled", - "severity": "MEDIUM", - "line": 4, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - GCP Compute Logging Service Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - GCP Compute Logging Service Disabled", + "severity": "MEDIUM", + "line": 3, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - GCP Compute Logging Service Disabled", + "severity": "MEDIUM", + "line": 4, + "fileName": "positive3.tf" + } +] From 4e914d9eac417016f4ba9b200e17f35c2793f21c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:22 +0100 Subject: [PATCH 337/900] fix(tests): update queryName to Beta prefix in gcp_gke_default_service_account_used --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive_expected_result.json index 1fc03b54785..eaa3a7bdedc 100644 --- a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "GKE Default Service Account Used", - "severity": "HIGH", - "line": 5, - "fileName": "positive1.tf" - }, - { - "queryName": "GKE Default Service Account Used", - "severity": "HIGH", - "line": 5, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - GKE Default Service Account Used", + "severity": "HIGH", + "line": 5, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - GKE Default Service Account Used", + "severity": "HIGH", + "line": 5, + "fileName": "positive2.tf" + } +] From d9df04743ea4a64817611a00d809df2868828d29 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:24 +0100 Subject: [PATCH 338/900] fix(tests): update queryName to Beta prefix in gcp_gke_image_vulnerability_scanning_disabled --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive_expected_result.json index 96bf72e2d4e..56713472795 100644 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "GKE Image Vulnerability Scanning Disabled", - "severity": "HIGH", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "GKE Image Vulnerability Scanning Disabled", - "severity": "HIGH", - "line": 4, - "fileName": "positive2.tf" - }, - { - "queryName": "GKE Image Vulnerability Scanning Disabled", - "severity": "HIGH", - "line": 6, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - GKE Image Vulnerability Scanning Disabled", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - GKE Image Vulnerability Scanning Disabled", + "severity": "HIGH", + "line": 4, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - GKE Image Vulnerability Scanning Disabled", + "severity": "HIGH", + "line": 6, + "fileName": "positive3.tf" + } +] From cc37c95c3cb74909a2d33db93dcbb02d37f8655e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:25 +0100 Subject: [PATCH 339/900] fix(tests): update queryName to Beta prefix in gcp_gke_manual_iam_check --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive_expected_result.json index c62bc67dd8a..2c12870e544 100644 --- a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "GKE Service Account IAM Review (Manual)", - "severity": "INFO", - "line": 7, - "fileName": "positive1.tf" - }, - { - "queryName": "GKE Service Account IAM Review (Manual)", - "severity": "INFO", - "line": 7, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - GKE Service Account IAM Review (Manual)", + "severity": "INFO", + "line": 7, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - GKE Service Account IAM Review (Manual)", + "severity": "INFO", + "line": 7, + "fileName": "positive2.tf" + } +] From 2510f5fb27956288a8978d876a8aa94f61404db9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:26 +0100 Subject: [PATCH 340/900] fix(tests): update queryName to Beta prefix in gcp_gke_metadata_server_disabled --- .../test/positive_expected_result.json | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive_expected_result.json index defbff8b43b..db46fc5bc4c 100644 --- a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive_expected_result.json @@ -1,26 +1,26 @@ -[ - { - "queryName": "GKE Metadata Server Disabled", - "severity": "HIGH", - "line": 5, - "fileName": "positive1.tf" - }, - { - "queryName": "GKE Metadata Server Disabled", - "severity": "HIGH", - "line": 5, - "fileName": "positive2.tf" - }, - { - "queryName": "GKE Metadata Server Disabled", - "severity": "HIGH", - "line": 6, - "fileName": "positive3.tf" - }, - { - "queryName": "GKE Metadata Server Disabled", - "severity": "HIGH", - "line": 7, - "fileName": "positive4.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - GKE Metadata Server Disabled", + "severity": "HIGH", + "line": 5, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - GKE Metadata Server Disabled", + "severity": "HIGH", + "line": 5, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - GKE Metadata Server Disabled", + "severity": "HIGH", + "line": 6, + "fileName": "positive3.tf" + }, + { + "queryName": "Beta - GKE Metadata Server Disabled", + "severity": "HIGH", + "line": 7, + "fileName": "positive4.tf" + } +] From 02e9bb48719f841ba3f67ad1f2442ae520a315a3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:28 +0100 Subject: [PATCH 341/900] fix(tests): update queryName to Beta prefix in gcp_gke_sandbox_disabled --- .../test/positive_expected_result.json | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive_expected_result.json index 3e0a67ec379..74f648f06f4 100644 --- a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive_expected_result.json @@ -1,26 +1,26 @@ -[ - { - "queryName": "GKE Sandbox (gVisor) Disabled", - "severity": "LOW", - "line": 5, - "fileName": "positive1.tf" - }, - { - "queryName": "GKE Sandbox (gVisor) Disabled", - "severity": "LOW", - "line": 5, - "fileName": "positive2.tf" - }, - { - "queryName": "GKE Sandbox (gVisor) Disabled", - "severity": "LOW", - "line": 6, - "fileName": "positive3.tf" - }, - { - "queryName": "GKE Sandbox (gVisor) Disabled", - "severity": "LOW", - "line": 7, - "fileName": "positive4.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - GKE Sandbox (gVisor) Disabled", + "severity": "LOW", + "line": 5, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - GKE Sandbox (gVisor) Disabled", + "severity": "LOW", + "line": 5, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - GKE Sandbox (gVisor) Disabled", + "severity": "LOW", + "line": 6, + "fileName": "positive3.tf" + }, + { + "queryName": "Beta - GKE Sandbox (gVisor) Disabled", + "severity": "LOW", + "line": 7, + "fileName": "positive4.tf" + } +] From 95a210792e9ef9f28c07c1023be75a6668b16d08 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:29 +0100 Subject: [PATCH 342/900] fix(tests): update queryName to Beta prefix in gcp_gke_secrets_encryption_cmek_disabled --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive_expected_result.json index cf68e051c08..547afcd982b 100644 --- a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "GKE Secrets Not Encrypted with CMEK", - "severity": "HIGH", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "GKE Secrets Not Encrypted with CMEK", - "severity": "HIGH", - "line": 5, - "fileName": "positive2.tf" - }, - { - "queryName": "GKE Secrets Not Encrypted with CMEK", - "severity": "HIGH", - "line": 5, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - GKE Secrets Not Encrypted with CMEK", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - GKE Secrets Not Encrypted with CMEK", + "severity": "HIGH", + "line": 5, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - GKE Secrets Not Encrypted with CMEK", + "severity": "HIGH", + "line": 5, + "fileName": "positive3.tf" + } +] From b3a0b118a0d073bd6d8000be81fd8944bc0523b0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:30 +0100 Subject: [PATCH 343/900] fix(tests): update queryName to Beta prefix in gcp_gke_security_posture_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive_expected_result.json index 6a757660260..5cd5538234d 100644 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "GKE Security Posture Disabled (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "GKE Security Posture Disabled (Manual)", - "severity": "INFO", - "line": 5, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - GKE Security Posture Disabled (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - GKE Security Posture Disabled (Manual)", + "severity": "INFO", + "line": 5, + "fileName": "positive2.tf" + } +] From 207cc39489b6822f1e552f1a9b82ea81de0fa85e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:32 +0100 Subject: [PATCH 344/900] fix(tests): update queryName to Beta prefix in gcp_gke_workload_identity_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive_expected_result.json index 1c56c81e5e8..07fa9009143 100644 --- a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "GKE Workload Identity & Dedicated SA (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "GKE Workload Identity & Dedicated SA (Manual)", - "severity": "INFO", - "line": 4, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - GKE Workload Identity & Dedicated SA (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - GKE Workload Identity & Dedicated SA (Manual)", + "severity": "INFO", + "line": 4, + "fileName": "positive2.tf" + } +] From 5501f18a0e3ceef22a5100fb6883105a6009224c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:33 +0100 Subject: [PATCH 345/900] fix(tests): update queryName to Beta prefix in gcp_http_load_balancer_logging_disabled --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive_expected_result.json index 1caf795a721..4226138823e 100644 --- a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "GCP HTTP(S) Load Balancer Logging Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "GCP HTTP(S) Load Balancer Logging Disabled", - "severity": "MEDIUM", - "line": 5, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - GCP HTTP(S) Load Balancer Logging Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - GCP HTTP(S) Load Balancer Logging Disabled", + "severity": "MEDIUM", + "line": 5, + "fileName": "positive2.tf" + } +] From b1d060b1c644c034d3633f5da9c74e543ee4a098 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:34 +0100 Subject: [PATCH 346/900] fix(tests): update queryName to Beta prefix in gcp_iap_backend_service_disabled --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive_expected_result.json index 89832969a28..ab14a7e30e6 100644 --- a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "IAP Disabled on Backend Service", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "IAP Disabled on Backend Service", - "severity": "MEDIUM", - "line": 3, - "fileName": "positive2.tf" - }, - { - "queryName": "IAP Disabled on Backend Service", - "severity": "MEDIUM", - "line": 3, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IAP Disabled on Backend Service", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - IAP Disabled on Backend Service", + "severity": "MEDIUM", + "line": 3, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - IAP Disabled on Backend Service", + "severity": "MEDIUM", + "line": 3, + "fileName": "positive3.tf" + } +] From af212f07a1ae260393c9c55ebe490ffcd7e2a725 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:36 +0100 Subject: [PATCH 347/900] fix(tests): update queryName to Beta prefix in gcp_sql_postgresql_log_error_verbosity_verbose --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive_expected_result.json index 1f14d5137b6..84103c5fd5a 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Cloud SQL PostgreSQL log_error_verbosity is Verbose", - "severity": "MEDIUM", - "line": 7, - "fileName": "positive1.tf" - }, - { - "queryName": "Cloud SQL PostgreSQL log_error_verbosity is Verbose", - "severity": "MEDIUM", - "line": 8, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Cloud SQL PostgreSQL log_error_verbosity is Verbose", + "severity": "MEDIUM", + "line": 7, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Cloud SQL PostgreSQL log_error_verbosity is Verbose", + "severity": "MEDIUM", + "line": 8, + "fileName": "positive2.tf" + } +] From 959b6ebe43a3b364904958d4b05f1b1ae31d06dd Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:37 +0100 Subject: [PATCH 348/900] fix(tests): update queryName to Beta prefix in gcp_sql_postgresql_log_statement_improperly_set --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive_expected_result.json index dd142772ba1..e0cd0a3e3cc 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Cloud SQL PostgreSQL log_statement Improperly Set", - "severity": "MEDIUM", - "line": 7, - "fileName": "positive1.tf" - }, - { - "queryName": "Cloud SQL PostgreSQL log_statement Improperly Set", - "severity": "MEDIUM", - "line": 6, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Cloud SQL PostgreSQL log_statement Improperly Set", + "severity": "MEDIUM", + "line": 7, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Cloud SQL PostgreSQL log_statement Improperly Set", + "severity": "MEDIUM", + "line": 6, + "fileName": "positive2.tf" + } +] From 06d25e7de432bc40b4fd9ede69d8d8c576e1e727 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:38 +0100 Subject: [PATCH 349/900] fix(tests): update queryName to Beta prefix in ibm_activity_tracker_global_events_disabled --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive_expected_result.json index 04f21d98a44..b7a53df26d0 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Activity Tracker for Global Events Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Activity Tracker for Global Events Disabled", - "severity": "MEDIUM", - "line": 9, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Activity Tracker for Global Events Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Activity Tracker for Global Events Disabled", + "severity": "MEDIUM", + "line": 9, + "fileName": "positive2.tf" + } +] From 8a13b4bbcc04d0b29c9b6cc5b0d38999ea787575 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:39 +0100 Subject: [PATCH 350/900] fix(tests): update queryName to Beta prefix in ibm_activity_tracker_platform_logs_disabled --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive_expected_result.json index ebcb1e4e1b0..63b7313f3d1 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Activity Tracker Platform Logs Disabled", - "severity": "HIGH", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Activity Tracker Platform Logs Disabled", - "severity": "HIGH", - "line": 5, - "fileName": "positive2.tf" - }, - { - "queryName": "Activity Tracker Platform Logs Disabled", - "severity": "HIGH", - "line": 12, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Activity Tracker Platform Logs Disabled", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Activity Tracker Platform Logs Disabled", + "severity": "HIGH", + "line": 5, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Activity Tracker Platform Logs Disabled", + "severity": "HIGH", + "line": 12, + "fileName": "positive3.tf" + } +] From 678f4feb9584ab60135f62c2f1306c2c3249ebbe Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:41 +0100 Subject: [PATCH 351/900] fix(tests): update queryName to Beta prefix in ibm_block_storage_customer_encryption_unified --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive_expected_result.json index a9e0734f996..78a823b9db2 100644 --- a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "IBM Block Storage Encryption (CMK/BYOK/KYOK) Manual", - "severity": "INFO", - "line": 5, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IBM Block Storage Encryption (CMK/BYOK/KYOK) Manual", + "severity": "INFO", + "line": 5, + "fileName": "positive1.tf" + } +] From 2d39776d82294f3d5a966c27bd516231c6128a29 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:42 +0100 Subject: [PATCH 352/900] fix(tests): update queryName to Beta prefix in ibm_certificate_manager_auto_renew_disabled --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive_expected_result.json index 4680efed476..9ab1e9a9c1c 100644 --- a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Certificate Manager Auto Renew Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Certificate Manager Auto Renew Disabled", - "severity": "MEDIUM", - "line": 7, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Certificate Manager Auto Renew Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Certificate Manager Auto Renew Disabled", + "severity": "MEDIUM", + "line": 7, + "fileName": "positive2.tf" + } +] From 72145ae3f3e192cd674f748a6a7e841e5fa5badb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:43 +0100 Subject: [PATCH 353/900] fix(tests): update queryName to Beta prefix in ibm_cis_dns_not_proxied_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive_expected_result.json index 12c19487774..96feab4cb1e 100644 --- a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "IBM CIS DNS Record Not Proxied (Manual)", - "severity": "INFO", - "line": 9, - "fileName": "positive1.tf" - }, - { - "queryName": "IBM CIS DNS Record Not Proxied (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IBM CIS DNS Record Not Proxied (Manual)", + "severity": "INFO", + "line": 9, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - IBM CIS DNS Record Not Proxied (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + } +] From 9bd5a55acb8ba470fbfc22beba3b79722a991624 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:45 +0100 Subject: [PATCH 354/900] fix(tests): update queryName to Beta prefix in ibm_cis_waf_enabled_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive_expected_result.json index 0069e2c83b5..418d2a226b1 100644 --- a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "IBM CIS WAF Not Enabled (Manual)", - "severity": "INFO", - "line": 6, - "fileName": "positive1.tf" - }, - { - "queryName": "IBM CIS WAF Not Enabled (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IBM CIS WAF Not Enabled (Manual)", + "severity": "INFO", + "line": 6, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - IBM CIS WAF Not Enabled (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + } +] From 9e462396f95c607fb35c6d020b82976a77bd0de0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:46 +0100 Subject: [PATCH 355/900] fix(tests): update queryName to Beta prefix in ibm_cloudant_cmk_encryption_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive_expected_result.json index 7f0f616c691..3b1b66c50ea 100644 --- a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "IBM Cloudant Encryption with CMK (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "IBM Cloudant Encryption with CMK (Manual)", - "severity": "INFO", - "line": 7, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IBM Cloudant Encryption with CMK (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - IBM Cloudant Encryption with CMK (Manual)", + "severity": "INFO", + "line": 7, + "fileName": "positive2.tf" + } +] From 4bac3e2b059843616a9b867fbaa323ef339a37a9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:47 +0100 Subject: [PATCH 356/900] fix(tests): update queryName to Beta prefix in ibm_container_cluster_entitlement_check --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive_expected_result.json index b2aa6c25605..2c92f4ce39e 100644 --- a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "IBM Cluster Entitlement Key Missing (Automated)", - "severity": "INFO", - "line": 5, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IBM Cluster Entitlement Key Missing (Automated)", + "severity": "INFO", + "line": 5, + "fileName": "positive1.tf" + } +] From 3ce849266cefc43780e0dda29ef409e745377d73 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:48 +0100 Subject: [PATCH 357/900] fix(tests): update queryName to Beta prefix in ibm_container_registry_va_alerts_missing --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive_expected_result.json index f6feb25008e..d18a405c254 100644 --- a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "IBM Container Registry VA Alerts Missing (Automated)", - "severity": "MEDIUM", - "line": 5, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IBM Container Registry VA Alerts Missing (Automated)", + "severity": "MEDIUM", + "line": 5, + "fileName": "positive1.tf" + } +] From 240cb14b803affc4359598a792c51f13d9c429ca Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:50 +0100 Subject: [PATCH 358/900] fix(tests): update queryName to Beta prefix in ibm_cos_bucket_customer_encryption_unified --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive_expected_result.json index 1a8da52305e..4084c292010 100644 --- a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "IBM COS Bucket Encryption (CMK/BYOK/KYOK) Manual", - "severity": "INFO", - "line": 5, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IBM COS Bucket Encryption (CMK/BYOK/KYOK) Manual", + "severity": "INFO", + "line": 5, + "fileName": "positive1.tf" + } +] From 5911d7c6d128448e483c26fcccdc124deaf1b344 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:51 +0100 Subject: [PATCH 359/900] fix(tests): update queryName to Beta prefix in ibm_database_cmk_encryption_manual --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive_expected_result.json index 9385193bf19..6dc7d21c79e 100644 --- a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "IBM Cloud Database Without CMK (Manual)", - "severity": "INFO", - "line": 5, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IBM Cloud Database Without CMK (Manual)", + "severity": "INFO", + "line": 5, + "fileName": "positive1.tf" + } +] From 8e1a92bec2e3588e03d1eeba8e73f4aca52c7514 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:52 +0100 Subject: [PATCH 360/900] fix(tests): update queryName to Beta prefix in ibm_iam_account_ip_restrictions_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive_expected_result.json index 5f64891c33a..c01495e6203 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "IBM Account IP Restrictions (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "IBM Account IP Restrictions (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IBM Account IP Restrictions (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - IBM Account IP Restrictions (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + } +] From b509844023dac800bc6dcf49c1580d75cbd459a1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:54 +0100 Subject: [PATCH 361/900] fix(tests): update queryName to Beta prefix in ibm_iam_account_mfa_disabled --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive_expected_result.json index 6f93077e52d..2b80f04faed 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Account Level MFA Is Not Enforced", - "severity": "HIGH", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Account Level MFA Is Not Enforced", - "severity": "HIGH", - "line": 1, - "fileName": "positive2.tf" - }, - { - "queryName": "Account Level MFA Is Not Enforced", - "severity": "HIGH", - "line": 3, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Account Level MFA Is Not Enforced", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Account Level MFA Is Not Enforced", + "severity": "HIGH", + "line": 1, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Account Level MFA Is Not Enforced", + "severity": "HIGH", + "line": 3, + "fileName": "positive3.tf" + } +] From 6fed9272be451dbd31169f107f027fed9abbdc55 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:55 +0100 Subject: [PATCH 362/900] fix(tests): update queryName to Beta prefix in ibm_iam_api_key_unused_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive_expected_result.json index e17a67b4b7b..e0c60585c99 100644 --- a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "IBM Cloud API Keys Unused for 180 Days (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "IBM Cloud API Keys Unused for 180 Days (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IBM Cloud API Keys Unused for 180 Days (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - IBM Cloud API Keys Unused for 180 Days (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + } +] From 75eb0eccfd89d4d82bbca8d1c75c081d17f55a7b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:56 +0100 Subject: [PATCH 363/900] fix(tests): update queryName to Beta prefix in ibm_iam_owner_api_key_manual --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive_expected_result.json index 98f50c83fc9..9805e09df42 100644 --- a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "IBM Owner Account API Key (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IBM Owner Account API Key (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + } +] From d2872a9c3d9b125001a6f7ec4d9986cff5721d3a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:58 +0100 Subject: [PATCH 364/900] fix(tests): update queryName to Beta prefix in ibm_iam_policy_assigned_to_user_manual --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive_expected_result.json index fb108f03019..c09e24ba603 100644 --- a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "IBM IAM Policies Attached to Users (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IBM IAM Policies Attached to Users (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + } +] From 85f656e61f257862a97fff6ce8767f0a6c06d80c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:24:59 +0100 Subject: [PATCH 365/900] fix(tests): update queryName to Beta prefix in ibm_iam_restrict_apikey_creation_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive_expected_result.json index f0aa46eaf5e..eba5f840e4c 100644 --- a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Restrict API Key & Service ID Creation (Manual)", - "severity": "INFO", - "line": 3, - "fileName": "positive1.tf" - }, - { - "queryName": "Restrict API Key & Service ID Creation (Manual)", - "severity": "INFO", - "line": 3, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Restrict API Key & Service ID Creation (Manual)", + "severity": "INFO", + "line": 3, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Restrict API Key & Service ID Creation (Manual)", + "severity": "INFO", + "line": 3, + "fileName": "positive2.tf" + } +] From bb1e4695e2f103242965becec52ee97a550da171 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:00 +0100 Subject: [PATCH 366/900] fix(tests): update queryName to Beta prefix in ibm_iam_session_expiration_too_long --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive_expected_result.json index cccff9041d8..fb2df50cd07 100644 --- a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "IBM Account Session Expiration Too Long", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "IBM Account Session Expiration Too Long", - "severity": "MEDIUM", - "line": 2, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IBM Account Session Expiration Too Long", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - IBM Account Session Expiration Too Long", + "severity": "MEDIUM", + "line": 2, + "fileName": "positive2.tf" + } +] From 1b520552f4a3b9d703befcd44bc9d07919e7d84b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:02 +0100 Subject: [PATCH 367/900] fix(tests): update queryName to Beta prefix in ibm_iks_cluster_logging_disabled --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/positive_expected_result.json index 64f347ff4ab..5e5afe68105 100644 --- a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "IKS Cluster Logging Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IKS Cluster Logging Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] From cccd477930cf500d8fb3ff73a75dffbcd459b2fb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:03 +0100 Subject: [PATCH 368/900] fix(tests): update queryName to Beta prefix in ibm_iks_cluster_monitoring_disabled --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/positive_expected_result.json index 86cd6bc3981..37d0c8f249d 100644 --- a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "IKS Cluster Monitoring Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IKS Cluster Monitoring Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] From d92cd8d0bb1f3ebda0a2171ebfecabd2c6b330ac Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:04 +0100 Subject: [PATCH 369/900] fix(tests): update queryName to Beta prefix in ibm_instance_os_disk_encryption_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive_expected_result.json index 789fc08718a..d2f4f30fe32 100644 --- a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "IBM Instance OS Disk Encryption (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "IBM Instance OS Disk Encryption (Manual)", - "severity": "INFO", - "line": 6, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - IBM Instance OS Disk Encryption (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - IBM Instance OS Disk Encryption (Manual)", + "severity": "INFO", + "line": 6, + "fileName": "positive2.tf" + } +] From c6ba4d58f6db6decd04ecdb40f20adcab45def6c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:06 +0100 Subject: [PATCH 370/900] fix(tests): update queryName to Beta prefix in ibm_kms_key_rotation_disabled --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive_expected_result.json index c44e043a51f..5cc6a8f7111 100644 --- a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "KMS Key Rotation Disabled", - "severity": "HIGH", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "KMS Key Rotation Disabled", - "severity": "HIGH", - "line": 6, - "fileName": "positive2.tf" - }, - { - "queryName": "KMS Key Rotation Disabled", - "severity": "HIGH", - "line": 7, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - KMS Key Rotation Disabled", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - KMS Key Rotation Disabled", + "severity": "HIGH", + "line": 6, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - KMS Key Rotation Disabled", + "severity": "HIGH", + "line": 7, + "fileName": "positive3.tf" + } +] From 0c21b30c7dee1a23b136eb188218b57a14ed595b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:07 +0100 Subject: [PATCH 371/900] fix(tests): update queryName to Beta prefix in ibm_logdna_archiving_disabled --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/positive_expected_result.json index 836d3c1acc4..24e3d4673cc 100644 --- a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "LogDNA Archiving Is Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - LogDNA Archiving Is Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + } +] From d0871aba6ce8bf923efb5ffe6c677c69ded2db0d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:08 +0100 Subject: [PATCH 372/900] fix(tests): update queryName to Beta prefix in ibm_logdna_view_without_alert --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/positive_expected_result.json index dfaed345f44..24661cc514d 100644 --- a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/positive_expected_result.json +++ b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "LogDNA View Without Alert", - "severity": "LOW", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - LogDNA View Without Alert", + "severity": "LOW", + "line": 1, + "fileName": "positive1.tf" + } +] From d91fe73cabc6e897bf80cc9bfcc022300b78f55c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:10 +0100 Subject: [PATCH 373/900] fix(tests): update queryName to Beta prefix in oci_cloud_guard_problem_event_rule_missing --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive_expected_result.json index 0c87e86299f..05df2922272 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Event Rule for Cloud Guard Problems is Missing", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Event Rule for Cloud Guard Problems is Missing", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive2.tf" - }, - { - "queryName": "Event Rule for Cloud Guard Problems is Missing", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Event Rule for Cloud Guard Problems is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Event Rule for Cloud Guard Problems is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Event Rule for Cloud Guard Problems is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive3.tf" + } +] From 4bccf0bce4c1f86abef025a0f61b762cbba3f0d7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:11 +0100 Subject: [PATCH 374/900] fix(tests): update queryName to Beta prefix in oci_cloud_guard_root_compartment_disabled --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive_expected_result.json index 6aa60561436..5f83235c125 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Cloud Guard Not Enabled at Root Compartment", - "severity": "HIGH", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Cloud Guard Not Enabled at Root Compartment", - "severity": "HIGH", - "line": 8, - "fileName": "positive2.tf" - }, - { - "queryName": "Cloud Guard Not Enabled at Root Compartment", - "severity": "HIGH", - "line": 7, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Cloud Guard Not Enabled at Root Compartment", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Cloud Guard Not Enabled at Root Compartment", + "severity": "HIGH", + "line": 8, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Cloud Guard Not Enabled at Root Compartment", + "severity": "HIGH", + "line": 7, + "fileName": "positive3.tf" + } +] From 9541eb53dec3edff443d8dd7cb919ac17efc14b8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:12 +0100 Subject: [PATCH 375/900] fix(tests): update queryName to Beta prefix in oci_compute_legacy_metadata_enabled --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive_expected_result.json index 5ec1f031f8e..4d3afc502f4 100644 --- a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Compute Instance Legacy Metadata Enabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Compute Instance Legacy Metadata Enabled", - "severity": "MEDIUM", - "line": 6, - "fileName": "positive2.tf" - }, - { - "queryName": "Compute Instance Legacy Metadata Enabled", - "severity": "MEDIUM", - "line": 8, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Compute Instance Legacy Metadata Enabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Compute Instance Legacy Metadata Enabled", + "severity": "MEDIUM", + "line": 6, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Compute Instance Legacy Metadata Enabled", + "severity": "MEDIUM", + "line": 8, + "fileName": "positive3.tf" + } +] From 7f1175ddf18ea2ae9db5146488c2abc4f416fdbe Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:13 +0100 Subject: [PATCH 376/900] fix(tests): update queryName to Beta prefix in oci_compute_secure_boot_disabled --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive_expected_result.json index 27215cd5562..d38c7976531 100644 --- a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Compute Instance Secure Boot Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Compute Instance Secure Boot Disabled", - "severity": "MEDIUM", - "line": 6, - "fileName": "positive2.tf" - }, - { - "queryName": "Compute Instance Secure Boot Disabled", - "severity": "MEDIUM", - "line": 8, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Compute Instance Secure Boot Disabled", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Compute Instance Secure Boot Disabled", + "severity": "MEDIUM", + "line": 6, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Compute Instance Secure Boot Disabled", + "severity": "MEDIUM", + "line": 8, + "fileName": "positive3.tf" + } +] From bca46db56caba28429b071001df0ce2472997191 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:15 +0100 Subject: [PATCH 377/900] fix(tests): update queryName to Beta prefix in oci_default_tags_not_defined --- .../test/positive_expected_result.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/oci/oci_default_tags_not_defined/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_default_tags_not_defined/test/positive_expected_result.json index cba73e9f9be..d0bce8b1511 100644 --- a/assets/queries/terraform/oci/oci_default_tags_not_defined/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_default_tags_not_defined/test/positive_expected_result.json @@ -1,8 +1,8 @@ -[ - { - "queryName": "Default Tags Not Defined", - "severity": "LOW", - "line": 1, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Default Tags Not Defined", + "severity": "LOW", + "line": 1, + "fileName": "positive1.tf" + } +] From dbced413311359f2cc9030fe874b9294dc686bae Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:17 +0100 Subject: [PATCH 378/900] fix(tests): update queryName to Beta prefix in oci_iam_group_change_event_rule_missing --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/positive_expected_result.json index 4f9befaadb5..530343df1a8 100644 --- a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Event Rule for IAM Group Changes is Missing", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Event Rule for IAM Group Changes is Missing", - "severity": "MEDIUM", - "line": 10, - "fileName": "positive2.tf" - }, - { - "queryName": "Event Rule for IAM Group Changes is Missing", - "severity": "MEDIUM", - "line": 8, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Event Rule for IAM Group Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Event Rule for IAM Group Changes is Missing", + "severity": "MEDIUM", + "line": 10, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Event Rule for IAM Group Changes is Missing", + "severity": "MEDIUM", + "line": 8, + "fileName": "positive3.tf" + } +] From 22e1bb1a93ac2744af0c4763a8871dc9c13ea5cc Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:18 +0100 Subject: [PATCH 379/900] fix(tests): update queryName to Beta prefix in oci_iam_password_expiration_manual --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive_expected_result.json index dd9cd8a4534..b04f83f241e 100644 --- a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "OCI IAM Password Expiration (365 days)", - "severity": "INFO", - "line": 5, - "fileName": "positive1.tf" - }, - { - "queryName": "OCI IAM Password Expiration (365 days)", - "severity": "INFO", - "line": 1, - "fileName": "positive2.tf" - }, - { - "queryName": "OCI IAM Password Expiration (365 days)", - "severity": "INFO", - "line": 1, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - OCI IAM Password Expiration (365 days)", + "severity": "INFO", + "line": 5, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - OCI IAM Password Expiration (365 days)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - OCI IAM Password Expiration (365 days)", + "severity": "INFO", + "line": 1, + "fileName": "positive3.tf" + } +] From 134b6012bf600d298e397ef2b7529216ba814cc9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:19 +0100 Subject: [PATCH 380/900] fix(tests): update queryName to Beta prefix in oci_iam_password_policy_length --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive_expected_result.json index 7eba7d84d20..41429b260a1 100644 --- a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "OCI IAM Password Minimum Length", - "severity": "MEDIUM", - "line": 6, - "fileName": "positive1.tf" - }, - { - "queryName": "OCI IAM Password Minimum Length", - "severity": "MEDIUM", - "line": 4, - "fileName": "positive2.tf" - }, - { - "queryName": "OCI IAM Password Minimum Length", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - OCI IAM Password Minimum Length", + "severity": "MEDIUM", + "line": 6, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - OCI IAM Password Minimum Length", + "severity": "MEDIUM", + "line": 4, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - OCI IAM Password Minimum Length", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive3.tf" + } +] From ded72a8d5b03c6814cacfb7bf7098b1b155018f1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:21 +0100 Subject: [PATCH 381/900] fix(tests): update queryName to Beta prefix in oci_iam_password_reuse_manual --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive_expected_result.json index 0376d3837d8..f9b0e975e10 100644 --- a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "OCI IAM Password Reuse Prevention (Manual)", - "severity": "INFO", - "line": 6, - "fileName": "positive1.tf" - }, - { - "queryName": "OCI IAM Password Reuse Prevention (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive2.tf" - }, - { - "queryName": "OCI IAM Password Reuse Prevention (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - OCI IAM Password Reuse Prevention (Manual)", + "severity": "INFO", + "line": 6, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - OCI IAM Password Reuse Prevention (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - OCI IAM Password Reuse Prevention (Manual)", + "severity": "INFO", + "line": 1, + "fileName": "positive3.tf" + } +] From ae8a7bb7547e7c15238de2bd5700667e8e14fd1b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:22 +0100 Subject: [PATCH 382/900] fix(tests): update queryName to Beta prefix in oci_iam_policy_change_event_rule_missing --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive_expected_result.json index 3653af125a1..c66835f31e2 100644 --- a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Event Rule for IAM Policy Changes is Missing", - "severity": "HIGH", - "line": 2, - "fileName": "positive1.tf" - }, - { - "queryName": "Event Rule for IAM Policy Changes is Missing", - "severity": "HIGH", - "line": 11, - "fileName": "positive2.tf" - }, - { - "queryName": "Event Rule for IAM Policy Changes is Missing", - "severity": "HIGH", - "line": 25, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Event Rule for IAM Policy Changes is Missing", + "severity": "HIGH", + "line": 2, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Event Rule for IAM Policy Changes is Missing", + "severity": "HIGH", + "line": 11, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Event Rule for IAM Policy Changes is Missing", + "severity": "HIGH", + "line": 25, + "fileName": "positive3.tf" + } +] From 1a843a45c6d5efdf00046badb06c311a2c5da5a4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:24 +0100 Subject: [PATCH 383/900] fix(tests): update queryName to Beta prefix in oci_iam_service_admins_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/positive_expected_result.json index c85bd5b053a..e2028843e90 100644 --- a/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_iam_service_admins_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "OCI Service Level Admins (Manual)", - "severity": "INFO", - "line": 10, - "fileName": "positive1.tf" - }, - { - "queryName": "OCI Service Level Admins (Manual)", - "severity": "INFO", - "line": 20, - "fileName": "positive1.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - OCI Service Level Admins (Manual)", + "severity": "INFO", + "line": 10, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - OCI Service Level Admins (Manual)", + "severity": "INFO", + "line": 20, + "fileName": "positive1.tf" + } +] From a1cd66521570dae740ee1ecdbd46e3ee014e00c2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:25 +0100 Subject: [PATCH 384/900] fix(tests): update queryName to Beta prefix in oci_iam_user_change_event_rule_missing --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive_expected_result.json index 2c81ca8e5ee..649145ecade 100644 --- a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Event Rule for IAM User Changes is Missing", - "severity": "HIGH", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Event Rule for IAM User Changes is Missing", - "severity": "HIGH", - "line": 11, - "fileName": "positive2.tf" - }, - { - "queryName": "Event Rule for IAM User Changes is Missing", - "severity": "HIGH", - "line": 27, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Event Rule for IAM User Changes is Missing", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Event Rule for IAM User Changes is Missing", + "severity": "HIGH", + "line": 11, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Event Rule for IAM User Changes is Missing", + "severity": "HIGH", + "line": 27, + "fileName": "positive3.tf" + } +] From db9995f041a86083050e9cd712175f9f2a80e0b2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:26 +0100 Subject: [PATCH 385/900] fix(tests): update queryName to Beta prefix in oci_idp_change_event_rule_missing --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive_expected_result.json index 5159aacc2cc..07dcb523f80 100644 --- a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Event Rule for Identity Provider Changes is Missing", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Event Rule for Identity Provider Changes is Missing", - "severity": "MEDIUM", - "line": 23, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Event Rule for Identity Provider Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Event Rule for Identity Provider Changes is Missing", + "severity": "MEDIUM", + "line": 23, + "fileName": "positive2.tf" + } +] From 809c0188f55eaa94e1a73c6af5ab99ea56a7d1f6 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:27 +0100 Subject: [PATCH 386/900] fix(tests): update queryName to Beta prefix in oci_idp_group_mapping_change_event_rule_missing --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive_expected_result.json index fc56ddcb96d..ab3c242c5e9 100644 --- a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Event Rule for IdP Group Mapping Changes is Missing", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Event Rule for IdP Group Mapping Changes is Missing", - "severity": "MEDIUM", - "line": 23, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Event Rule for IdP Group Mapping Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Event Rule for IdP Group Mapping Changes is Missing", + "severity": "MEDIUM", + "line": 23, + "fileName": "positive2.tf" + } +] From 0d2c969c1c296a4be1451cc9d3f26f4011ad5963 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:29 +0100 Subject: [PATCH 387/900] fix(tests): update queryName to Beta prefix in oci_instance_transit_encryption --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive_expected_result.json index 2099845fc82..dbd0a6d1d71 100644 --- a/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "OCI Instance In-Transit Encryption Disabled", - "severity": "MEDIUM", - "line": 13, - "fileName": "positive1.tf" - }, - { - "queryName": "OCI Instance In-Transit Encryption Disabled", - "severity": "MEDIUM", - "line": 11, - "fileName": "positive2.tf" - }, - { - "queryName": "OCI Instance In-Transit Encryption Disabled", - "severity": "MEDIUM", - "line": 5, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - OCI Instance In-Transit Encryption Disabled", + "severity": "MEDIUM", + "line": 13, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - OCI Instance In-Transit Encryption Disabled", + "severity": "MEDIUM", + "line": 11, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - OCI Instance In-Transit Encryption Disabled", + "severity": "MEDIUM", + "line": 5, + "fileName": "positive3.tf" + } +] From 90caeb5a505aa5800218406973ff0779e3ca828a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:30 +0100 Subject: [PATCH 388/900] fix(tests): update queryName to Beta prefix in oci_local_user_authentication_event_rule_missing --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive_expected_result.json index 3f13367b2a8..aceb34d8437 100644 --- a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Event Rule for Local User Authentication is Missing", - "severity": "HIGH", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Event Rule for Local User Authentication is Missing", - "severity": "HIGH", - "line": 23, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Event Rule for Local User Authentication is Missing", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Event Rule for Local User Authentication is Missing", + "severity": "HIGH", + "line": 23, + "fileName": "positive2.tf" + } +] From e3d940bb87dea2ac6cdd8efdff174d5939cae1db Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:31 +0100 Subject: [PATCH 389/900] fix(tests): update queryName to Beta prefix in oci_network_gateway_change_event_rule_missing --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive_expected_result.json index 170738f4e34..acc708ee10b 100644 --- a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Event Rule for Network Gateway Changes is Missing", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Event Rule for Network Gateway Changes is Missing", - "severity": "MEDIUM", - "line": 11, - "fileName": "positive2.tf" - }, - { - "queryName": "Event Rule for Network Gateway Changes is Missing", - "severity": "MEDIUM", - "line": 37, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Event Rule for Network Gateway Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Event Rule for Network Gateway Changes is Missing", + "severity": "MEDIUM", + "line": 11, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Event Rule for Network Gateway Changes is Missing", + "severity": "MEDIUM", + "line": 37, + "fileName": "positive3.tf" + } +] From 1217fd45b64d6d930d06dc0376a1a79b85f042dd Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:33 +0100 Subject: [PATCH 390/900] fix(tests): update queryName to Beta prefix in oci_notification_topic_without_subscription --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive_expected_result.json index 3cc75e994c7..19040b914e2 100644 --- a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Notification Topic Without Subscription", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Notification Topic Without Subscription", - "severity": "MEDIUM", - "line": 6, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Notification Topic Without Subscription", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Notification Topic Without Subscription", + "severity": "MEDIUM", + "line": 6, + "fileName": "positive2.tf" + } +] From 7cb3d34bfed82252a9c92ff609a723b837b5734b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:34 +0100 Subject: [PATCH 391/900] fix(tests): update queryName to Beta prefix in oci_nsg_change_event_rule_missing --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive_expected_result.json index 9eedb1c4941..41ea867293b 100644 --- a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Event Rule for NSG Changes is Missing", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Event Rule for NSG Changes is Missing", - "severity": "MEDIUM", - "line": 11, - "fileName": "positive2.tf" - }, - { - "queryName": "Event Rule for NSG Changes is Missing", - "severity": "MEDIUM", - "line": 25, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Event Rule for NSG Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Event Rule for NSG Changes is Missing", + "severity": "MEDIUM", + "line": 11, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Event Rule for NSG Changes is Missing", + "severity": "MEDIUM", + "line": 25, + "fileName": "positive3.tf" + } +] From 5337c74695cdee16c9f0257061547edfa3e9eef6 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:36 +0100 Subject: [PATCH 392/900] fix(tests): update queryName to Beta prefix in oci_objectstorage_bucket_logging_enabled --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive_expected_result.json index 92add310abf..71df47eb85d 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Object Storage Bucket Logging Disabled", - "severity": "MEDIUM", - "line": 5, - "fileName": "positive1.tf" - }, - { - "queryName": "Object Storage Bucket Logging Disabled", - "severity": "MEDIUM", - "line": 11, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Object Storage Bucket Logging Disabled", + "severity": "MEDIUM", + "line": 5, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Object Storage Bucket Logging Disabled", + "severity": "MEDIUM", + "line": 11, + "fileName": "positive2.tf" + } +] From e4b182880f956555cd7457007091914ff9b8abba Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:37 +0100 Subject: [PATCH 393/900] fix(tests): update queryName to Beta prefix in oci_objectstorage_bucket_versioning_disabled --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive_expected_result.json index 6e91b54c4a4..1906578a1a0 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Object Storage Bucket Versioning Disabled", - "severity": "MEDIUM", - "line": 5, - "fileName": "positive1.tf" - }, - { - "queryName": "Object Storage Bucket Versioning Disabled", - "severity": "MEDIUM", - "line": 11, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Object Storage Bucket Versioning Disabled", + "severity": "MEDIUM", + "line": 5, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Object Storage Bucket Versioning Disabled", + "severity": "MEDIUM", + "line": 11, + "fileName": "positive2.tf" + } +] From 366e9912f4de7b6f3e23eb038fc59fb4052eb2f0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:38 +0100 Subject: [PATCH 394/900] fix(tests): update queryName to Beta prefix in oci_resource_created_in_root_compartment --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive_expected_result.json index 3d6d6db9c73..f1c9954b581 100644 --- a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "Resource Created In Root Compartment", - "severity": "HIGH", - "line": 10, - "fileName": "positive1.tf" - }, - { - "queryName": "Resource Created In Root Compartment", - "severity": "HIGH", - "line": 9, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Resource Created In Root Compartment", + "severity": "HIGH", + "line": 10, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Resource Created In Root Compartment", + "severity": "HIGH", + "line": 9, + "fileName": "positive2.tf" + } +] From 516b5f1c97bacafe3dac525f4dd19a92a21a4608 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:40 +0100 Subject: [PATCH 395/900] fix(tests): update queryName to Beta prefix in oci_route_table_change_event_rule_missing --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive_expected_result.json index d4502f2e88f..a263781a9bb 100644 --- a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Event Rule for Route Table Changes is Missing", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Event Rule for Route Table Changes is Missing", - "severity": "MEDIUM", - "line": 11, - "fileName": "positive2.tf" - }, - { - "queryName": "Event Rule for Route Table Changes is Missing", - "severity": "MEDIUM", - "line": 25, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Event Rule for Route Table Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Event Rule for Route Table Changes is Missing", + "severity": "MEDIUM", + "line": 11, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Event Rule for Route Table Changes is Missing", + "severity": "MEDIUM", + "line": 25, + "fileName": "positive3.tf" + } +] From dc47bd9dbd9a3a46340c73598460b7b3f6ee3882 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:41 +0100 Subject: [PATCH 396/900] fix(tests): update queryName to Beta prefix in oci_security_list_change_event_rule_missing --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive_expected_result.json index 7b344cdf4f9..039fbe2170b 100644 --- a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Event Rule for Security List Changes is Missing", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Event Rule for Security List Changes is Missing", - "severity": "MEDIUM", - "line": 10, - "fileName": "positive2.tf" - }, - { - "queryName": "Event Rule for Security List Changes is Missing", - "severity": "MEDIUM", - "line": 24, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Event Rule for Security List Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Event Rule for Security List Changes is Missing", + "severity": "MEDIUM", + "line": 10, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Event Rule for Security List Changes is Missing", + "severity": "MEDIUM", + "line": 24, + "fileName": "positive3.tf" + } +] From 1e90f30df1eb584963ef7b1e9f9a10a2378cadba Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:42 +0100 Subject: [PATCH 397/900] fix(tests): update queryName to Beta prefix in oci_storage_admin_no_delete_manual --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive_expected_result.json index e4a32105d59..0e46cd2dc21 100644 --- a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "OCI Storage Admin with Delete Privileges (Manual)", - "severity": "INFO", - "line": 10, - "fileName": "positive1.tf" - }, - { - "queryName": "OCI Storage Admin with Delete Privileges (Manual)", - "severity": "INFO", - "line": 10, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - OCI Storage Admin with Delete Privileges (Manual)", + "severity": "INFO", + "line": 10, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - OCI Storage Admin with Delete Privileges (Manual)", + "severity": "INFO", + "line": 10, + "fileName": "positive2.tf" + } +] From 9eb56f2deddf7772f68bbe6ee1f89aeed08be7b0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:44 +0100 Subject: [PATCH 398/900] fix(tests): update queryName to Beta prefix in oci_storage_cmk_encryption_unified --- .../test/positive_expected_result.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive_expected_result.json index a762ba46ea8..7da1b413ab4 100644 --- a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive_expected_result.json @@ -1,14 +1,14 @@ -[ - { - "queryName": "OCI Storage Resources Without CMK", - "severity": "MEDIUM", - "line": 5, - "fileName": "positive1.tf" - }, - { - "queryName": "OCI Storage Resources Without CMK", - "severity": "MEDIUM", - "line": 10, - "fileName": "positive2.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - OCI Storage Resources Without CMK", + "severity": "MEDIUM", + "line": 5, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - OCI Storage Resources Without CMK", + "severity": "MEDIUM", + "line": 10, + "fileName": "positive2.tf" + } +] From 3c56fcc67c6a5fa6c8b0063cac751be8db3957a5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:45 +0100 Subject: [PATCH 399/900] fix(tests): update queryName to Beta prefix in oci_subnet_flow_logging_disabled --- .../test/positive_expected_result.json | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive_expected_result.json index 487c19e8a97..fc5152e402f 100644 --- a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive_expected_result.json @@ -1,26 +1,26 @@ -[ - { - "queryName": "VCN Subnet Without Flow Log", - "severity": "HIGH", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "VCN Subnet Without Flow Log", - "severity": "HIGH", - "line": 7, - "fileName": "positive2.tf" - }, - { - "queryName": "VCN Subnet Without Flow Log", - "severity": "HIGH", - "line": 6, - "fileName": "positive3.tf" - }, - { - "queryName": "VCN Subnet Without Flow Log", - "severity": "HIGH", - "line": 11, - "fileName": "positive4.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - VCN Subnet Without Flow Log", + "severity": "HIGH", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - VCN Subnet Without Flow Log", + "severity": "HIGH", + "line": 7, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - VCN Subnet Without Flow Log", + "severity": "HIGH", + "line": 6, + "fileName": "positive3.tf" + }, + { + "queryName": "Beta - VCN Subnet Without Flow Log", + "severity": "HIGH", + "line": 11, + "fileName": "positive4.tf" + } +] From 40fb322cf641deeaf1f26f55f9ca86d1bca9f895 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 19:25:46 +0100 Subject: [PATCH 400/900] fix(tests): update queryName to Beta prefix in oci_vcn_change_event_rule_missing --- .../test/positive_expected_result.json | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive_expected_result.json index 7789396e1ca..e9d47b8ab38 100644 --- a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/test/positive_expected_result.json @@ -1,20 +1,20 @@ -[ - { - "queryName": "Event Rule for VCN Changes is Missing", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Event Rule for VCN Changes is Missing", - "severity": "MEDIUM", - "line": 10, - "fileName": "positive2.tf" - }, - { - "queryName": "Event Rule for VCN Changes is Missing", - "severity": "MEDIUM", - "line": 24, - "fileName": "positive3.tf" - } -] \ No newline at end of file +[ + { + "queryName": "Beta - Event Rule for VCN Changes is Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Event Rule for VCN Changes is Missing", + "severity": "MEDIUM", + "line": 10, + "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Event Rule for VCN Changes is Missing", + "severity": "MEDIUM", + "line": 24, + "fileName": "positive3.tf" + } +] From 767b621fb368b20afc6764a4091b7af1b54a584a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:32 +0100 Subject: [PATCH 401/900] fix(metadata): correct description/url for azure_elastic_san_public_access_enabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json index cb1888c8c59..b77bb94b391 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "660863a5-bb45-4907-8afe-d7478177a446", - "queryName": "Beta - Elastic SAN Public Network Access Enabled", - "severity": "HIGH", - "category": "Networking and Firewall", - "descriptionText": "Ensures that 'public_network_access_enabled' is set to false for Azure Elastic SAN. Disabling public access ensures that the SAN is only accessible via private endpoints within the virtual network.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/elastic_san#public_network_access_enabled", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "284", - "descriptionID": "660863a5", - "riskScore": "9.0", - "experimental": "true" +{ + "id": "660863a5-bb45-4907-8afe-d7478177a446", + "queryName": "Beta - Elastic SAN Public Network Access Enabled", + "severity": "HIGH", + "category": "Networking and Firewall", + "descriptionText": "Ensures that Azure Elastic SAN Volume Groups have network rules configured to restrict public network access to approved virtual networks only. Volume groups without a network_rule block allow unrestricted public access to storage volumes.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/elastic_san_volume_group#network_rule", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "284", + "descriptionID": "660863a5", + "riskScore": "9.0", + "experimental": "true" } \ No newline at end of file From e340f731babfb183256e604087619705fa7fac51 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:33 +0100 Subject: [PATCH 402/900] fix(metadata): correct description/url for azure_backup_vault_infrastructure_encryption_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json index cef98b348f8..7c56130a381 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "f7bf03d5-ae0e-4b36-aab3-f8d2346a8843", - "queryName": "Beta - Backup Vault Infrastructure Encryption Disabled", - "severity": "MEDIUM", - "category": "Encryption", - "descriptionText": "Ensures that 'Infrastructure Encryption' is enabled for Azure Backup Vaults. This provides a second layer of encryption (double encryption) for data at rest.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/data_protection_backup_vault#infrastructure_encryption_enabled", - "platform": "Terraform", - "descriptionID": "f7bf03d5", - "cloudProvider": "azure", - "cwe": "312", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "f7bf03d5-ae0e-4b36-aab3-f8d2346a8843", + "queryName": "Beta - Backup Vault Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that Azure Backup Vaults have a managed identity configured. A managed identity is required to support advanced encryption features including customer-managed keys (CMK) and infrastructure encryption.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/data_protection_backup_vault#identity", + "platform": "Terraform", + "descriptionID": "f7bf03d5", + "cloudProvider": "azure", + "cwe": "312", + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From ba274da76d59b57b5b8278288a76e9dfdc804d7a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:34 +0100 Subject: [PATCH 403/900] fix(metadata): correct description/url for azure_mysql_audit_log_enabled_manual --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json index b787e21ce68..303681b40f8 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "8d8ac482-16c2-4eb7-bfab-e2d94d035498", - "queryName": "Beta - MySQL Audit Log Enabled (Manual)", - "severity": "INFO", - "category": "Observability", - "descriptionText": "Ensures that the 'audit_log_enabled' server parameter is set to 'ON' for Azure MySQL Database Servers. Since this parameter is often managed via runtime configurations or separate resources, manual verification is required.", - "descriptionUrl": "https://learn.microsoft.com/en-us/azure/mysql/single-server/concepts-audit-logs", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "778", - "descriptionID": "8d8ac482", - "riskScore": "0.0", - "experimental": "true" +{ + "id": "8d8ac482-16c2-4eb7-bfab-e2d94d035498", + "queryName": "Beta - MySQL Audit Log Enabled (Manual)", + "severity": "INFO", + "category": "Observability", + "descriptionText": "Ensures that audit logging is enabled for Azure MySQL Flexible Server and Azure SQL Server (MSSQL) instances. Since audit log settings are managed via server parameters outside Terraform, manual verification is required.", + "descriptionUrl": "https://learn.microsoft.com/en-us/azure/mysql/single-server/concepts-audit-logs", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "778", + "descriptionID": "8d8ac482", + "riskScore": "0.0", + "experimental": "true" } \ No newline at end of file From 6f84e91bb013b85b51a00a08935ba713ecfe7612 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:36 +0100 Subject: [PATCH 404/900] fix(metadata): correct description/url for azure_mysql_audit_log_events_connection_manual --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json index 87dac00f41c..c2915fda6fa 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "fe65cd89-28ea-4301-9c50-6dee30553557", - "queryName": "Beta - MySQL Audit Log Events Connection (Manual)", - "severity": "INFO", - "category": "Observability", - "descriptionText": "Ensures that the 'audit_log_events' server parameter includes 'CONNECTION' for Azure MySQL Database Servers. This ensures that successful and failed connection attempts are logged.", - "descriptionUrl": "https://learn.microsoft.com/en-us/azure/mysql/single-server/concepts-audit-logs", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "778", - "descriptionID": "fe65cd89", - "riskScore": "0.0", - "experimental": "true" +{ + "id": "fe65cd89-28ea-4301-9c50-6dee30553557", + "queryName": "Beta - MySQL Audit Log Events Connection (Manual)", + "severity": "INFO", + "category": "Observability", + "descriptionText": "Ensures that the 'audit_log_events' server parameter includes 'CONNECTION' for Azure MySQL Flexible Server and Azure SQL Server (MSSQL) instances, capturing successful and failed connection attempts. Manual verification is required.", + "descriptionUrl": "https://learn.microsoft.com/en-us/azure/mysql/single-server/concepts-audit-logs", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "778", + "descriptionID": "fe65cd89", + "riskScore": "0.0", + "experimental": "true" } \ No newline at end of file From 765b2bbf9dd478418579af2feb9897726d490ac5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:37 +0100 Subject: [PATCH 405/900] fix(metadata): correct description/url for oci_compute_secure_boot_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json index 359f0601df4..f44266025ee 100644 --- a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "1f24d72d-c8be-403f-92b8-84ed910fe96e", - "queryName": "Beta - Compute Instance Secure Boot Disabled", - "severity": "MEDIUM", - "category": "Insecure Configurations", - "descriptionText": "Ensures that OCI Compute Instances have Secure Boot enabled. Secure Boot is a feature of UEFI firmware that helps prevent unauthorized boot loaders and operating systems from loading during the startup process, protecting against rootkits and boot-level malware.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_instance#is_secure_boot_enabled", - "platform": "Terraform", - "descriptionID": "1f24d72d", - "cloudProvider": "oci", - "cwe": "427", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "1f24d72d-c8be-403f-92b8-84ed910fe96e", + "queryName": "Beta - Compute Instance Secure Boot Disabled", + "severity": "MEDIUM", + "category": "Insecure Configurations", + "descriptionText": "Ensures that OCI Compute Instances have a platform configuration block (platform_config) defined with is_secure_boot_enabled set to true. Secure Boot prevents unauthorized firmware and operating systems from loading during instance startup, protecting against rootkits and boot-level malware.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_instance#platform_config", + "platform": "Terraform", + "descriptionID": "1f24d72d", + "cloudProvider": "oci", + "cwe": "427", + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From ed1ad94683de8aab71865a861bfe93be586b1d38 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:38 +0100 Subject: [PATCH 406/900] fix(metadata): correct description/url for ibm_container_registry_va_alerts_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json index efbe7647d8a..bbbaca424ec 100644 --- a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json +++ b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "92440d0d-889c-49c5-a0e6-13c5f326b872", - "queryName": "Beta - IBM Container Registry VA Alerts Missing (Automated)", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that notifications are enabled for the Vulnerability Advisor (VA) in IBM Cloud Container Registry. The resource 'ibm_container_va_notification' allows configuring alerts (email, webhook) for new vulnerabilities found in container images.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/container_va_notification", - "platform": "Terraform", - "descriptionID": "92440d0d", - "cloudProvider": "ibm", - "cwe": "778", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "92440d0d-889c-49c5-a0e6-13c5f326b872", + "queryName": "Beta - IBM Container Registry VA Alerts Missing (Automated)", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that IBM Kubernetes Service (IKS) clusters have a Vulnerability Advisor notification resource (ibm_container_va_notification) configured, enabling container vulnerability alerts from IBM Cloud Container Registry.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/container_cluster", + "platform": "Terraform", + "descriptionID": "92440d0d", + "cloudProvider": "ibm", + "cwe": "778", + "riskScore": 3.0, + "experimental": "true" } \ No newline at end of file From 6fe428544255c2f61f399c120735b6d4cbb30911 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:40 +0100 Subject: [PATCH 407/900] fix(metadata): correct description/url for azure_managed_lustre_cmk_encryption_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json index 64309fc9853..7b7b731cc78 100644 --- a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "7fc653e2-af91-4379-9219-5095caba0ff6", - "queryName": "Beta - Azure Managed Lustre Not Encrypted with CMK", - "severity": "MEDIUM", - "category": "Encryption", - "descriptionText": "Ensures that Azure Managed Lustre file systems are encrypted using a Customer-Managed Key (CMK). By default, data is encrypted with platform-managed keys, but CMK provides full control over key rotation and access policies.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/managed_lustre_file_system#key_encryption_key", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "326", - "descriptionID": "7fc653e2", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "7fc653e2-af91-4379-9219-5095caba0ff6", + "queryName": "Beta - Azure Managed Lustre Not Encrypted with CMK", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that Azure Managed Lustre file systems are encrypted using a Customer-Managed Key (CMK). By default, data is encrypted with platform-managed keys, but CMK provides full control over key rotation and access policies.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/managed_lustre_file_system#encryption_key", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "326", + "descriptionID": "7fc653e2", + "riskScore": "5.0", + "experimental": "true" } \ No newline at end of file From 4638d98c5e4064389cdcfa97add014c0bf175b39 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:41 +0100 Subject: [PATCH 408/900] fix(queries): remove azure_defender_easm_enabled_manual from PR --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json deleted file mode 100644 index 7d9de00665c..00000000000 --- a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "b9f8511b-bd48-4e9d-8439-94e49e671490", - "queryName": "Beta - Microsoft Defender EASM Enabled (Manual)", - "severity": "INFO", - "category": "Observability", - "descriptionText": "Ensures that Microsoft Defender External Attack Surface Monitoring (EASM) is enabled. Since EASM cannot be fully configured or verified via standard Terraform resources yet, this rule serves as a manual reminder to verify the service in the Azure Portal.", - "descriptionUrl": "https://azure.microsoft.com/en-us/products/defender-easm/", - "platform": "Terraform", - "descriptionID": "b9f8511b", - "cloudProvider": "azure", - "cwe": "778", - "riskScore": "0.0", - "experimental": "true" -} \ No newline at end of file From 8f99b02ecc88273161ced24168c2ba19d5162e73 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:41 +0100 Subject: [PATCH 409/900] fix(metadata): correct description/url for azure_storage_blob_logging_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json index 6a571e788e9..0a4360ef5bd 100644 --- a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "11fa88c0-2064-48ee-8431-953c7d961c71", - "queryName": "Beta - Storage Blob Service Logging Disabled", - "severity": "LOW", - "category": "Observability", - "descriptionText": "Ensures that Storage Logging is enabled for the Blob service for 'Read', 'Write', and 'Delete' requests. This provides an audit trail of operations performed on blobs and containers.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#logging", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "778", - "descriptionID": "11fa88c0", - "riskScore": "2.0", - "experimental": "true" +{ + "id": "11fa88c0-2064-48ee-8431-953c7d961c71", + "queryName": "Beta - Storage Blob Service Logging Disabled", + "severity": "LOW", + "category": "Observability", + "descriptionText": "Ensures that Storage Logging is enabled for the Blob service for 'Read', 'Write', and 'Delete' requests. This provides an audit trail of operations performed on blobs and containers.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/monitor_diagnostic_setting", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "778", + "descriptionID": "11fa88c0", + "riskScore": "2.0", + "experimental": "true" } \ No newline at end of file From 44bc51831c4b4d54a64cadc78a43678d3136d1d2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:42 +0100 Subject: [PATCH 410/900] fix(queries): remove azure_defender_easm_enabled_manual from PR --- .../azure_defender_easm_enabled_manual/test/negative1.tf | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/negative1.tf diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/negative1.tf b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/negative1.tf deleted file mode 100644 index c8ce844cce0..00000000000 --- a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/negative1.tf +++ /dev/null @@ -1,7 +0,0 @@ -resource "azurerm_storage_account" "no_rg_here" { - name = "storageaccountneg1" - resource_group_name = "rg-existing" - location = "East US" - account_tier = "Standard" - account_replication_type = "LRS" -} From c24b31340c846224b432afebf7ca63d35ce294f5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:42 +0100 Subject: [PATCH 411/900] fix(metadata): correct description/url for azure_storage_table_logging_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json index 3fabe299d93..c7ced4d9035 100644 --- a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "0d29e3cf-0033-4ca6-9b97-fa3e6c4d25b8", - "queryName": "Beta - Storage Table Service Logging Disabled", - "severity": "LOW", - "category": "Observability", - "descriptionText": "Ensures that Storage Logging is enabled for the Table service for 'Read', 'Write', and 'Delete' requests. This provides an audit trail of operations performed on NoSQL tables within the storage account.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#logging", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "778", - "descriptionID": "0d29e3cf", - "riskScore": "2.0", - "experimental": "true" +{ + "id": "0d29e3cf-0033-4ca6-9b97-fa3e6c4d25b8", + "queryName": "Beta - Storage Table Service Logging Disabled", + "severity": "LOW", + "category": "Observability", + "descriptionText": "Ensures that Storage Logging is enabled for the Table service for 'Read', 'Write', and 'Delete' requests. This provides an audit trail of operations performed on NoSQL tables within the storage account.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/monitor_diagnostic_setting", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "778", + "descriptionID": "0d29e3cf", + "riskScore": "2.0", + "experimental": "true" } \ No newline at end of file From 988640993381c2d237d5c227bf384fe3b48bc505 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:43 +0100 Subject: [PATCH 412/900] fix(queries): remove azure_defender_easm_enabled_manual from PR --- .../test/positive_expected_result.json | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive_expected_result.json diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive_expected_result.json deleted file mode 100644 index e3d5fa7f0bf..00000000000 --- a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive_expected_result.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "queryName": "Beta - Microsoft Defender EASM Enabled (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - } -] From d9bb59d5198924492ae9919b4da3aaae9433e36f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:44 +0100 Subject: [PATCH 413/900] fix(metadata): correct description/url for oci_subnet_flow_logging_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json index a23b9fd88ab..f62afaa45da 100644 --- a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "30d3bb83-f6aa-4302-a647-c404f12f8b8a", - "queryName": "Beta - VCN Subnet Without Flow Log", - "severity": "HIGH", - "category": "Observability", - "descriptionText": "VCN Subnet should have flow logging enabled to monitor traffic, as per CIS v3.0.0 recommendation 4.13.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_subnet", - "platform": "Terraform", - "descriptionID": "30d3bb83", - "cloudProvider": "oci", - "cwe": "778", - "riskScore": 6.0, - "experimental": "true" +{ + "id": "30d3bb83-f6aa-4302-a647-c404f12f8b8a", + "queryName": "Beta - VCN Subnet Without Flow Log", + "severity": "HIGH", + "category": "Observability", + "descriptionText": "VCN Subnet should have flow logging enabled to monitor traffic, as per CIS v3.0.0 recommendation 4.13.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/logging_log", + "platform": "Terraform", + "descriptionID": "30d3bb83", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": 6.0, + "experimental": "true" } \ No newline at end of file From b6e15813289facba656914decd188c71f4d64bf9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:45 +0100 Subject: [PATCH 414/900] fix(queries): remove ibm_iam_api_key_unused_manual from PR --- .../ibm_iam_api_key_unused_manual/metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json deleted file mode 100644 index f3f5bfb44a9..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "a2b88f1a-038f-4898-a7c1-61eb2aa41143", - "queryName": "Beta - IBM Cloud API Keys Unused for 180 Days (Manual)", - "severity": "INFO", - "category": "Observability", - "descriptionText": "Terraform cannot detect if an IBM Cloud IAM API Key is unused. This rule flags the creation of API Keys to remind the auditor to establish an automated process to detect and disable keys unused for 180 days.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_api_key", - "platform": "Terraform", - "descriptionID": "a2b88f1a", - "cloudProvider": "ibm", - "cwe": "798", - "riskScore": 0.0, - "experimental": "true" -} \ No newline at end of file From 8063c473ab07ae3e51271d8e75f9d425422ac839 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:46 +0100 Subject: [PATCH 415/900] fix(queries): remove ibm_iam_api_key_unused_manual from PR --- .../ibm_iam_api_key_unused_manual/query.rego | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/query.rego diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/query.rego b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/query.rego deleted file mode 100644 index 76f1454c05a..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/query.rego +++ /dev/null @@ -1,29 +0,0 @@ -package Cx - -# CASO 1: IBM Cloud IAM API Key (Usuario). -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.ibm_iam_api_key[name] - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_iam_api_key.%s", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "An external process should monitor and disable this key if unused for 180 days", - "keyActualValue": "IBM IAM User API Key created via Terraform. Manual verification of lifecycle policy required.", - } -} - -# CASO 2: IBM Cloud IAM Service API Key (Service ID). -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.ibm_iam_service_api_key[name] - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_iam_service_api_key.%s", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "An external process should monitor and disable this key if unused for 180 days", - "keyActualValue": "IBM IAM Service API Key created via Terraform. Manual verification of lifecycle policy required.", - } -} \ No newline at end of file From 3223e80e1d35e098c4326f219ac0029374639410 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:46 +0100 Subject: [PATCH 416/900] fix(queries): remove ibm_iam_api_key_unused_manual from PR --- .../ibm/ibm_iam_api_key_unused_manual/test/negative1.tf | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/negative1.tf diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/negative1.tf deleted file mode 100644 index 28dbe58cfe0..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/negative1.tf +++ /dev/null @@ -1,8 +0,0 @@ -# El cumplimiento es "negativo" cuando no hay recursos de claves de API que requieran monitoreo de ciclo de vida. -resource "ibm_is_vpc" "safe_vpc" { - name = "compliant-vpc" -} - -resource "ibm_iam_access_group" "acc_group" { - name = "test-group" -} \ No newline at end of file From b5f7f11d1b1bdd457ea2d2bce5301566b934dea4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:47 +0100 Subject: [PATCH 417/900] fix(queries): remove ibm_iam_api_key_unused_manual from PR --- .../ibm/ibm_iam_api_key_unused_manual/test/positive1.tf | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive1.tf diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive1.tf deleted file mode 100644 index bbcaa0dfd23..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive1.tf +++ /dev/null @@ -1,3 +0,0 @@ -resource "ibm_iam_api_key" "personal_key" { - name = "admin-key" -} \ No newline at end of file From 711fd264a948ee0b1cd4e88c4f122db2c695cf3a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:49 +0100 Subject: [PATCH 418/900] fix(queries): remove ibm_iam_api_key_unused_manual from PR --- .../ibm/ibm_iam_api_key_unused_manual/test/positive2.tf | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive2.tf diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive2.tf b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive2.tf deleted file mode 100644 index e2d54fb69f0..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive2.tf +++ /dev/null @@ -1,4 +0,0 @@ -resource "ibm_iam_service_api_key" "app_key" { - name = "automation-key" - service_id_crn = "crn:v1:bluemix:public:iam-identity::a/123::serviceid:ServiceId-123" -} \ No newline at end of file From 9609616987b6aa5bdb9e4a17f77be56fe4a783dc Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:49 +0100 Subject: [PATCH 419/900] fix(queries): remove ibm_iam_api_key_unused_manual from PR --- .../test/positive_expected_result.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive_expected_result.json diff --git a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive_expected_result.json deleted file mode 100644 index e0c60585c99..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_api_key_unused_manual/test/positive_expected_result.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "queryName": "Beta - IBM Cloud API Keys Unused for 180 Days (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Beta - IBM Cloud API Keys Unused for 180 Days (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive2.tf" - } -] From 0f464d7bf70711afecc688c8b1506ae67a3c7bc2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:51 +0100 Subject: [PATCH 420/900] fix(queries): remove ibm_iam_owner_api_key_manual from PR --- .../ibm/ibm_iam_owner_api_key_manual/metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json deleted file mode 100644 index de01413b4ed..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "dae483b9-d462-49d1-993c-4d398cad281e", - "queryName": "Beta - IBM Owner Account API Key (Manual)", - "severity": "INFO", - "category": "Access Control", - "descriptionText": "The account owner should not have an associated API Key. Using owner credentials implies unlimited privileges and poses a catastrophic risk if compromised. Verify that this API Key does not belong to the Account Owner.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_api_key", - "platform": "Terraform", - "descriptionID": "dae483b9", - "cloudProvider": "ibm", - "cwe": "269", - "riskScore": 0.0, - "experimental": "true" -} \ No newline at end of file From dc8c56359586e44a0c7f2c1ccdbf5b5782bea5dc Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:52 +0100 Subject: [PATCH 421/900] fix(queries): remove ibm_iam_owner_api_key_manual from PR --- .../ibm/ibm_iam_owner_api_key_manual/query.rego | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/query.rego diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/query.rego b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/query.rego deleted file mode 100644 index 5ed5881e0d0..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/query.rego +++ /dev/null @@ -1,15 +0,0 @@ -package Cx - -# CASO 1: Detección de API Key de Usuario. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.ibm_iam_api_key[name] - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_iam_api_key.%s", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "The API Key should belong to a functional user or Service ID, NEVER the Account Owner", - "keyActualValue": "IBM IAM User API Key detected. Verify this key is NOT for the Account Owner.", - } -} \ No newline at end of file From cd871567e4177f02adc99125ba5e1b6e54e6deaa Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:52 +0100 Subject: [PATCH 422/900] fix(queries): remove ibm_iam_owner_api_key_manual from PR --- .../ibm/ibm_iam_owner_api_key_manual/test/negative1.tf | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/negative1.tf diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/negative1.tf deleted file mode 100644 index 430cc21292a..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/negative1.tf +++ /dev/null @@ -1,9 +0,0 @@ -# Las claves de Service ID son el estándar seguro y no disparan esta alerta -resource "ibm_iam_service_id" "service_id" { - name = "safe-service" -} - -resource "ibm_iam_service_api_key" "service_key" { - name = "safe-key" - iam_service_id = ibm_iam_service_id.service_id.iam_id -} \ No newline at end of file From f4448f9e452f9d71bf6dc85c35ff472d637ed336 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:53 +0100 Subject: [PATCH 423/900] fix(queries): remove ibm_iam_owner_api_key_manual from PR --- .../ibm/ibm_iam_owner_api_key_manual/test/positive1.tf | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive1.tf diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive1.tf deleted file mode 100644 index 4c8f76627cc..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive1.tf +++ /dev/null @@ -1,3 +0,0 @@ -resource "ibm_iam_api_key" "owner_candidate_key" { - name = "potential-owner-key" -} \ No newline at end of file From d7b42641e3fa6a4e9cd54415ae4868299f252112 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:54 +0100 Subject: [PATCH 424/900] fix(queries): remove ibm_iam_owner_api_key_manual from PR --- .../test/positive_expected_result.json | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive_expected_result.json diff --git a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive_expected_result.json deleted file mode 100644 index 9805e09df42..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_owner_api_key_manual/test/positive_expected_result.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "queryName": "Beta - IBM Owner Account API Key (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - } -] From e07a6fb3e3d119604be610c6aec094fce29e801d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:56 +0100 Subject: [PATCH 425/900] fix(queries): remove ibm_iam_policy_assigned_to_user_manual from PR --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json deleted file mode 100644 index 73d14879ab9..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "d08b8443-aa59-4099-9523-5cfc6bee1d4a", - "queryName": "Beta - IBM IAM Policies Attached to Users (Manual)", - "severity": "INFO", - "category": "Access Control", - "descriptionText": "Detects usage of 'ibm_iam_user_policy'. Access policies should be assigned to Access Groups ('ibm_iam_access_group_policy') rather than directly to users to ensure scalable and manageable IAM governance.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_user_policy", - "platform": "Terraform", - "descriptionID": "d08b8443", - "cloudProvider": "ibm", - "cwe": "284", - "riskScore": 0.0, - "experimental": "true" -} \ No newline at end of file From 3717756fd9d1724897c25f5c468ad97648d63995 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:56 +0100 Subject: [PATCH 426/900] fix(oci_compute_secure_boot_disabled): use platform_config instead of shape_config in Rego --- .../query.rego | 95 +++++++++---------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego index 1f132489d88..845d60034fa 100644 --- a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego @@ -1,48 +1,47 @@ -package Cx - -# REGLA 1: Falta el bloque 'shape_config' por completo. -CxPolicy[result] { - instance := input.document[i].resource.oci_core_instance[instance_name] - - not instance.shape_config - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_core_instance.%s", [instance_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'shape_config' block should be defined", - "keyActualValue": "'shape_config' block is missing", - } -} - -# REGLA 2: Existe 'shape_config', pero falta el atributo dentro. -CxPolicy[result] { - instance := input.document[i].resource.oci_core_instance[instance_name] - shape_config := instance.shape_config - - object.get(shape_config, "is_secure_boot_enabled", null) == null - - result := { - "documentId": input.document[i].id, - # Apuntamos al bloque shape_config - "searchKey": sprintf("resource.oci_core_instance.%s.shape_config", [instance_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'is_secure_boot_enabled' should be present inside 'shape_config' and set to 'true'", - "keyActualValue": "'is_secure_boot_enabled' is missing inside 'shape_config'", - } -} - -# REGLA 3: El atributo existe pero es 'false'. -CxPolicy[result] { - instance := input.document[i].resource.oci_core_instance[instance_name] - - instance.shape_config.is_secure_boot_enabled == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_core_instance.%s.shape_config.is_secure_boot_enabled", [instance_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'is_secure_boot_enabled' attribute should be 'true'", - "keyActualValue": "'is_secure_boot_enabled' attribute is 'false'", - } -} \ No newline at end of file +package Cx + +# RULE 1: The 'platform_config' block is missing entirely. +CxPolicy[result] { + instance := input.document[i].resource.oci_core_instance[instance_name] + + not instance.platform_config + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_core_instance.%s", [instance_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'platform_config' block should be defined with 'is_secure_boot_enabled' set to true", + "keyActualValue": "'platform_config' block is missing", + } +} + +# RULE 2: 'platform_config' exists but 'is_secure_boot_enabled' is missing. +CxPolicy[result] { + instance := input.document[i].resource.oci_core_instance[instance_name] + platform_config := instance.platform_config + + object.get(platform_config, "is_secure_boot_enabled", null) == null + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_core_instance.%s.platform_config", [instance_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'is_secure_boot_enabled' should be present inside 'platform_config' and set to 'true'", + "keyActualValue": "'is_secure_boot_enabled' is missing inside 'platform_config'", + } +} + +# RULE 3: The attribute exists but is 'false'. +CxPolicy[result] { + instance := input.document[i].resource.oci_core_instance[instance_name] + + instance.platform_config.is_secure_boot_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_core_instance.%s.platform_config.is_secure_boot_enabled", [instance_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_secure_boot_enabled' attribute should be 'true'", + "keyActualValue": "'is_secure_boot_enabled' attribute is 'false'", + } +} From 0c19fe485183b3f72179c0e23f5cd60b0e732896 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:57 +0100 Subject: [PATCH 427/900] fix(queries): remove ibm_iam_policy_assigned_to_user_manual from PR --- .../test/negative1.tf | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/negative1.tf diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/negative1.tf deleted file mode 100644 index 7febdcd80cc..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/negative1.tf +++ /dev/null @@ -1,14 +0,0 @@ -# Uso correcto de políticas mediante grupos de acceso -resource "ibm_iam_access_group" "auditors" { - name = "Audit-Team" -} - -resource "ibm_iam_access_group_policy" "group_policy" { - access_group_id = ibm_iam_access_group.auditors.id - roles = ["Viewer"] -} - -resource "ibm_iam_access_group_members" "members" { - access_group_id = ibm_iam_access_group.auditors.id - ibm_ids = ["auditor@company.com"] -} \ No newline at end of file From adeed6ed4d07bff35d58bdec77f4d83b69315ff2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:58 +0100 Subject: [PATCH 428/900] fix(queries): remove ibm_iam_policy_assigned_to_user_manual from PR --- .../test/positive1.tf | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive1.tf diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive1.tf deleted file mode 100644 index cbbb7c042be..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive1.tf +++ /dev/null @@ -1,8 +0,0 @@ -resource "ibm_iam_user_policy" "insecure_policy" { - ibm_id = "auditor@company.com" - roles = ["Viewer"] - - resources { - resource_type = "resource-group" - } -} \ No newline at end of file From c7f518f15171dd97740526b06e01cac0fe659742 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:59 +0100 Subject: [PATCH 429/900] fix(queries): remove ibm_iam_policy_assigned_to_user_manual from PR --- .../test/positive_expected_result.json | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive_expected_result.json diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive_expected_result.json deleted file mode 100644 index c09e24ba603..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/test/positive_expected_result.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "queryName": "Beta - IBM IAM Policies Attached to Users (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - } -] From 5661a312c3955e54c05fc5d917c34103cdfefe08 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:17:59 +0100 Subject: [PATCH 430/900] fix(tests): update test/positive2.tf to use platform_config for oci_compute_secure_boot_disabled --- .../test/positive2.tf | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive2.tf b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive2.tf index d2385663e68..bf41e7ca019 100644 --- a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive2.tf @@ -1,10 +1,10 @@ -resource "oci_core_instance" "positive2" { - availability_domain = "AD-1" - compartment_id = "ocid1.compartment..." - shape = "VM.Standard2.1" - - shape_config { - # FALLO: Falta is_secure_boot_enabled (Caso 2) - ocpus = 1 - } -} \ No newline at end of file +resource "oci_core_instance" "positive2" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + + platform_config { + # FAIL: Missing is_secure_boot_enabled (Case 2) + type = "AMD_VM" + } +} From 2e26e64e929272a112905fa7d118c4ff71285a1a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:00 +0100 Subject: [PATCH 431/900] fix(queries): remove ibm_iam_restrict_apikey_creation_manual from PR --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json deleted file mode 100644 index 71a1b328bc2..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "30640fc8-88be-4053-882c-55fd0febaf3f", - "queryName": "Beta - Restrict API Key & Service ID Creation (Manual)", - "severity": "INFO", - "category": "Access Control", - "descriptionText": "CIS controls recommend restricting the creation of API Keys and Service IDs to privileged users only. Review IAM policies to ensure 'Editor' or 'Administrator' roles (or custom roles with creation actions) are not granted broadly.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_user_policy", - "platform": "Terraform", - "descriptionID": "30640fc8", - "cloudProvider": "ibm", - "cwe": "276", - "riskScore": 0.0, - "experimental": "true" -} \ No newline at end of file From af294ff04db72bd6be7a5db8336861e5452af698 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:01 +0100 Subject: [PATCH 432/900] fix(queries): remove ibm_iam_restrict_apikey_creation_manual from PR --- .../query.rego | 38 ------------------- 1 file changed, 38 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/query.rego diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/query.rego b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/query.rego deleted file mode 100644 index d60ab79cae8..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/query.rego +++ /dev/null @@ -1,38 +0,0 @@ -package Cx - -ensure_array(x) = x { is_array(x) } -ensure_array(x) = [x] { not is_array(x) } - -# CASO 1: Revisión de Políticas de Usuario (ibm_iam_user_policy). -CxPolicy[result] { - doc := input.document[i] - policy := doc.resource.ibm_iam_user_policy[name] - - roles := ensure_array(policy.roles) - count(roles) > 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_iam_user_policy.%s.roles", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "Roles should not grant 'iam.service_id.create' or 'iam.api_key.create' to non-privileged users", - "keyActualValue": sprintf("User policy grants roles: %v. Manual review required.", [roles]), - } -} - -# CASO 2: Revisión de Políticas de Grupo de Acceso (ibm_iam_access_group_policy). -CxPolicy[result] { - doc := input.document[i] - policy := doc.resource.ibm_iam_access_group_policy[name] - - roles := ensure_array(policy.roles) - count(roles) > 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_iam_access_group_policy.%s.roles", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "Roles should not grant 'iam.service_id.create' or 'iam.api_key.create' to non-privileged users", - "keyActualValue": sprintf("Access Group policy grants roles: %v. Manual review required.", [roles]), - } -} \ No newline at end of file From 5114a7def9bf5b857011e28384f607fa0fb4dacf Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:02 +0100 Subject: [PATCH 433/900] fix(tests): update test/negative1.tf to use platform_config for oci_compute_secure_boot_disabled --- .../test/negative1.tf | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/negative1.tf b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/negative1.tf index 744a095c1e3..e408e8df210 100644 --- a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/negative1.tf +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/negative1.tf @@ -1,10 +1,11 @@ -resource "oci_core_instance" "negative1" { - availability_domain = "AD-1" - compartment_id = "ocid1.compartment..." - shape = "VM.Standard2.1" - - shape_config { - # CORRECTO - is_secure_boot_enabled = true - } -} \ No newline at end of file +resource "oci_core_instance" "negative1" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + + platform_config { + # PASS: Secure Boot enabled + type = "AMD_VM" + is_secure_boot_enabled = true + } +} From 72dec64b9140b484c5179020a68326e3f34c0244 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:03 +0100 Subject: [PATCH 434/900] fix(queries): remove ibm_iam_restrict_apikey_creation_manual from PR --- .../test/positive1.tf | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive1.tf diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive1.tf deleted file mode 100644 index 8f249923af7..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive1.tf +++ /dev/null @@ -1,8 +0,0 @@ -resource "ibm_iam_user_policy" "high_privilege_user" { - ibm_id = "user@example.com" - roles = ["Administrator"] # Alerta: requiere revisión manual - - resources { - service = "iam-identity" - } -} \ No newline at end of file From 2d26e7e2e99fc5b70663400eaae4a5df600984b2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:04 +0100 Subject: [PATCH 435/900] fix(queries): remove ibm_iam_restrict_apikey_creation_manual from PR --- .../test/positive2.tf | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive2.tf diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive2.tf b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive2.tf deleted file mode 100644 index 372270cfa91..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive2.tf +++ /dev/null @@ -1,8 +0,0 @@ -resource "ibm_iam_access_group_policy" "broad_group_policy" { - access_group_id = "access-group-id" - roles = ["Editor", "Viewer"] # Alerta: Editor permite creación de credenciales - - resources { - service = "iam-identity" - } -} \ No newline at end of file From 86c8790bde1af5775abc620b3cf0e60a77ece1ae Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:05 +0100 Subject: [PATCH 436/900] fix(queries): remove ibm_iam_restrict_apikey_creation_manual from PR --- .../test/positive_expected_result.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive_expected_result.json diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive_expected_result.json deleted file mode 100644 index eba5f840e4c..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/positive_expected_result.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "queryName": "Beta - Restrict API Key & Service ID Creation (Manual)", - "severity": "INFO", - "line": 3, - "fileName": "positive1.tf" - }, - { - "queryName": "Beta - Restrict API Key & Service ID Creation (Manual)", - "severity": "INFO", - "line": 3, - "fileName": "positive2.tf" - } -] From 9c0666fc9e23623d9b014176a3edfbcd9a766b74 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:07 +0100 Subject: [PATCH 437/900] fix(queries): remove gcp_gke_workload_identity_manual from PR --- .../gcp_gke_workload_identity_manual/metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json deleted file mode 100644 index f240462ceff..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "edea054b-6ed2-4be2-bad2-459891848678", - "queryName": "Beta - GKE Workload Identity & Dedicated SA (Manual)", - "severity": "INFO", - "category": "Access Control", - "descriptionText": "Ensures that GKE clusters have Workload Identity enabled. If enabled, manual verification is required to ensure that workloads use dedicated Google Service Accounts (1:1 mapping) rather than shared ones.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_cluster#workload_identity_config", - "platform": "Terraform", - "descriptionID": "edea054b", - "cloudProvider": "gcp", - "cwe": "284", - "riskScore": "0.0", - "experimental": "true" -} \ No newline at end of file From 82058ce6ea82f9477e0a57c36c6a5dcfd88c2762 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:07 +0100 Subject: [PATCH 438/900] fix(queries): remove gcp_gke_workload_identity_manual from PR --- .../query.rego | 39 ------------------- 1 file changed, 39 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego deleted file mode 100644 index 84f83b69b72..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/query.rego +++ /dev/null @@ -1,39 +0,0 @@ -package Cx - -import data.generic.terraform as tf_lib - -# RULE 1: Workload Identity not enabled (Missing Attribute). -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - not cluster.workload_identity_config - - result := { - "documentId": doc.id, - "resourceType": "google_container_cluster", - "resourceName": tf_lib.get_resource_name(cluster, name), - "searchKey": sprintf("google_container_cluster[%s]", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'workload_identity_config' should be enabled to support dedicated Service Accounts", - "keyActualValue": "'workload_identity_config' is missing", - } -} - -# RULE 2: Workload Identity enabled (Manual Binding Verification). -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - cluster.workload_identity_config - - result := { - "documentId": doc.id, - "resourceType": "google_container_cluster", - "resourceName": tf_lib.get_resource_name(cluster, name), - "searchKey": sprintf("google_container_cluster[%s].workload_identity_config", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "Verify that workloads use dedicated Service Accounts (no shared SAs)", - "keyActualValue": "Workload Identity is enabled. Manual verification of bindings required.", - } -} From 991a29db612604980d151cb0d2e3497301eb745c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:08 +0100 Subject: [PATCH 439/900] fix(queries): remove gcp_gke_workload_identity_manual from PR --- .../gcp/gcp_gke_workload_identity_manual/test/negative1.tf | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/negative1.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/negative1.tf b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/negative1.tf deleted file mode 100644 index 015f1237ef7..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/negative1.tf +++ /dev/null @@ -1,4 +0,0 @@ -# Caso negativo: No hay clústeres GKE que auditar. -resource "google_compute_network" "vpc" { - name = "main-vpc" -} \ No newline at end of file From 6269b17e32c78cc3b5e240a5696ee5563b07736b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:09 +0100 Subject: [PATCH 440/900] fix(queries): remove gcp_gke_workload_identity_manual from PR --- .../gcp/gcp_gke_workload_identity_manual/test/positive1.tf | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive1.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive1.tf deleted file mode 100644 index 4521fa4170f..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive1.tf +++ /dev/null @@ -1,5 +0,0 @@ -resource "google_container_cluster" "fail_disabled" { - name = "insecure-cluster" - location = "us-central1" - # FALLO: Falta workload_identity_config -} \ No newline at end of file From f365d3fb427745768f8edeae135ecaef2a4802b7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:10 +0100 Subject: [PATCH 441/900] fix(queries): remove gcp_gke_workload_identity_manual from PR --- .../gcp_gke_workload_identity_manual/test/positive2.tf | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive2.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive2.tf deleted file mode 100644 index 058abb750cc..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive2.tf +++ /dev/null @@ -1,8 +0,0 @@ -resource "google_container_cluster" "fail_manual_check" { - name = "cluster-with-wi" - - workload_identity_config { - workload_pool = "my-project.svc.id.goog" - } - # INFO: Requiere revisión manual de los bindings de las aplicaciones -} \ No newline at end of file From 9d38b3fadda31ce97e2cd057869e435eadf07a35 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:11 +0100 Subject: [PATCH 442/900] fix(queries): remove gcp_gke_workload_identity_manual from PR --- .../test/positive_expected_result.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive_expected_result.json diff --git a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive_expected_result.json deleted file mode 100644 index 07fa9009143..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_workload_identity_manual/test/positive_expected_result.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "queryName": "Beta - GKE Workload Identity & Dedicated SA (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Beta - GKE Workload Identity & Dedicated SA (Manual)", - "severity": "INFO", - "line": 4, - "fileName": "positive2.tf" - } -] From fbb8ad5a93623dfc64b55ad5d824d0ca52b7ddb6 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:12 +0100 Subject: [PATCH 443/900] fix(queries): remove gcp_gke_manual_iam_check from PR --- .../gcp/gcp_gke_manual_iam_check/metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json deleted file mode 100644 index ea49720a364..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "b29ff836-5b2e-4089-a40c-086426ef3980", - "queryName": "Beta - GKE Service Account IAM Review (Manual)", - "severity": "INFO", - "category": "Supply-Chain", - "descriptionText": "A custom Service Account is configured for GKE nodes. Manual verification is required to ensure this account has Read-Only access to Container Registries (e.g., 'roles/storage.objectViewer') and not Write access.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam_member", - "platform": "Terraform", - "descriptionID": "b29ff836", - "cloudProvider": "gcp", - "cwe": "276", - "riskScore": "0.0", - "experimental": "true" -} \ No newline at end of file From 55422fc898174400c49d609ad7a194a70fd4e908 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:13 +0100 Subject: [PATCH 444/900] fix(queries): remove gcp_gke_manual_iam_check from PR --- .../gcp/gcp_gke_manual_iam_check/query.rego | 39 ------------------- 1 file changed, 39 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego deleted file mode 100644 index d7a7348ad02..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/query.rego +++ /dev/null @@ -1,39 +0,0 @@ -package Cx - -import data.generic.terraform as tf_lib - -# RULE 1: Detection of custom SA in google_container_cluster. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_container_cluster[name] - - sa := resource.node_config.service_account - - result := { - "documentId": doc.id, - "resourceType": "google_container_cluster", - "resourceName": tf_lib.get_resource_name(resource, name), - "searchKey": sprintf("google_container_cluster[%s].node_config.service_account", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "Custom Service Account IAM roles should be verified as Read-Only", - "keyActualValue": sprintf("Custom Service Account '%s' found. Manual IAM verification required.", [sa]), - } -} - -# RULE 2: Detection of custom SA in google_container_node_pool. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_container_node_pool[name] - - sa := resource.node_config.service_account - - result := { - "documentId": doc.id, - "resourceType": "google_container_node_pool", - "resourceName": tf_lib.get_resource_name(resource, name), - "searchKey": sprintf("google_container_node_pool[%s].node_config.service_account", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "Custom Service Account IAM roles should be verified as Read-Only", - "keyActualValue": sprintf("Custom Service Account '%s' found. Manual IAM verification required.", [sa]), - } -} From b3c6c2b15acb159c890a46129bd8c06d8ed7cfa6 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:14 +0100 Subject: [PATCH 445/900] fix(queries): remove gcp_gke_manual_iam_check from PR --- .../terraform/gcp/gcp_gke_manual_iam_check/test/negative1.tf | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/negative1.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/negative1.tf b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/negative1.tf deleted file mode 100644 index 85a988a70c7..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/negative1.tf +++ /dev/null @@ -1,5 +0,0 @@ -# En este caso negativo, no hay SA personalizada (se encargaría la regla de SA por defecto) -resource "google_container_cluster" "no_custom_sa" { - name = "default-sa-cluster" - # No define node_config.service_account -} \ No newline at end of file From 095c7cf0085e4d0e0474bfbfde2fff99e7928617 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:15 +0100 Subject: [PATCH 446/900] fix(queries): remove gcp_gke_manual_iam_check from PR --- .../gcp/gcp_gke_manual_iam_check/test/positive1.tf | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive1.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive1.tf deleted file mode 100644 index 72e297282f2..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive1.tf +++ /dev/null @@ -1,9 +0,0 @@ -resource "google_container_cluster" "audit_cluster" { - name = "custom-sa-cluster" - location = "us-central1" - - node_config { - # INFO: Esta cuenta requiere revisión manual de IAM - service_account = "gke-nodes-custom@project.iam.gserviceaccount.com" - } -} \ No newline at end of file From de2d4291ac20f35770d5a8569056011c1246c97b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:16 +0100 Subject: [PATCH 447/900] fix(queries): remove gcp_gke_manual_iam_check from PR --- .../gcp/gcp_gke_manual_iam_check/test/positive2.tf | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive2.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive2.tf deleted file mode 100644 index 5a9cf868c63..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive2.tf +++ /dev/null @@ -1,9 +0,0 @@ -resource "google_container_node_pool" "audit_pool" { - name = "custom-sa-pool" - cluster = "my-cluster" - - node_config { - # INFO: Esta cuenta requiere revisión manual de IAM - service_account = "dedicated-pool-sa@project.iam.gserviceaccount.com" - } -} \ No newline at end of file From fb8c43295fa9f0caae9e8782ca052cf7d72a95fe Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:16 +0100 Subject: [PATCH 448/900] fix(queries): remove gcp_gke_manual_iam_check from PR --- .../test/positive_expected_result.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive_expected_result.json diff --git a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive_expected_result.json deleted file mode 100644 index 2c12870e544..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_manual_iam_check/test/positive_expected_result.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "queryName": "Beta - GKE Service Account IAM Review (Manual)", - "severity": "INFO", - "line": 7, - "fileName": "positive1.tf" - }, - { - "queryName": "Beta - GKE Service Account IAM Review (Manual)", - "severity": "INFO", - "line": 7, - "fileName": "positive2.tf" - } -] From e6c7cc934753d28f2a0ca58508f2bfbdeaa99ed5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:18 +0100 Subject: [PATCH 449/900] fix(queries): remove azure_storage_critical_data_cmk_manual from PR --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json deleted file mode 100644 index 78d893e0ddf..00000000000 --- a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "20fcb3ef-4524-4d45-baa9-60b0eb229beb", - "queryName": "Beta - Critical Data Storage CMK (Manual)", - "severity": "INFO", - "category": "Encryption", - "descriptionText": "Identifies Storage Accounts using default Platform-Managed Keys. If these accounts store business-critical or sensitive data, they must be encrypted using Customer-Managed Keys (CMK). Manual verification of data sensitivity is required.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#customer_managed_key", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "312", - "descriptionID": "20fcb3ef", - "riskScore": "0.0", - "experimental": "true" -} \ No newline at end of file From 1420c1f9990b4274551a9311c563428db3e0c479 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:19 +0100 Subject: [PATCH 450/900] fix(queries): remove azure_storage_critical_data_cmk_manual from PR --- .../query.rego | 40 ------------------- 1 file changed, 40 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego deleted file mode 100644 index c9e0628b9ba..00000000000 --- a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/query.rego +++ /dev/null @@ -1,40 +0,0 @@ -package Cx - -import data.generic.terraform as tf_lib - -# RULE 1: The 'customer_managed_key' block does not exist. -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[name] - - not sa.customer_managed_key - - result := { - "documentId": doc.id, - "resourceType": "azurerm_storage_account", - "resourceName": tf_lib.get_resource_name(sa, name), - "searchKey": sprintf("azurerm_storage_account[%s]", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should use CMK if hosting critical data (Manual Verification)", [name]), - "keyActualValue": sprintf("'azurerm_storage_account.%s' is using Platform-Managed Keys", [name]), - } -} - -# RULE 2: The block exists but the 'key_vault_key_id' attribute is not defined. -CxPolicy[result] { - doc := input.document[i] - sa := doc.resource.azurerm_storage_account[name] - - sa.customer_managed_key - object.get(sa.customer_managed_key, "key_vault_key_id", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "resourceType": "azurerm_storage_account", - "resourceName": tf_lib.get_resource_name(sa, name), - "searchKey": sprintf("azurerm_storage_account[%s].customer_managed_key", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "If 'customer_managed_key' block is defined, it should include 'key_vault_key_id' for CMK encryption", - "keyActualValue": "'key_vault_key_id' is not defined within the 'customer_managed_key' block", - } -} From 1d7b8707875b941d2f2fd81b8ba3ed2b1ddf5471 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:20 +0100 Subject: [PATCH 451/900] fix(queries): remove azure_storage_critical_data_cmk_manual from PR --- .../test/negative1.tf | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/negative1.tf diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/negative1.tf b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/negative1.tf deleted file mode 100644 index 39bd87c0f6e..00000000000 --- a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/negative1.tf +++ /dev/null @@ -1,16 +0,0 @@ -resource "azurerm_storage_account" "pass" { - name = "st-pass-cmk" - resource_group_name = "rg" - location = "West Europe" - account_tier = "Standard" - account_replication_type = "LRS" - - identity { - type = "SystemAssigned" - } - - customer_managed_key { - key_vault_key_id = "https://kv.vault.azure.net/keys/key/v1" - user_assigned_identity_id = "some-id" - } -} \ No newline at end of file From af631f014a8375c065622a91d3dccbba52f99f4a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:21 +0100 Subject: [PATCH 452/900] fix(queries): remove azure_storage_critical_data_cmk_manual from PR --- .../test/positive1.tf | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive1.tf diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive1.tf b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive1.tf deleted file mode 100644 index 471c97fbe07..00000000000 --- a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive1.tf +++ /dev/null @@ -1,7 +0,0 @@ -resource "azurerm_storage_account" "fail_1" { - name = "st-no-cmk-block" - resource_group_name = "rg" - location = "West Europe" - account_tier = "Standard" - account_replication_type = "LRS" -} \ No newline at end of file From a7cdd6c70fac91fef2d7e61420d469656794045d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:21 +0100 Subject: [PATCH 453/900] fix(queries): remove azure_storage_critical_data_cmk_manual from PR --- .../test/positive2.tf | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive2.tf diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive2.tf b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive2.tf deleted file mode 100644 index b774263629d..00000000000 --- a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive2.tf +++ /dev/null @@ -1,11 +0,0 @@ -resource "azurerm_storage_account" "fail_2" { - name = "st-block-no-id" - resource_group_name = "rg" - location = "West Europe" - account_tier = "Standard" - account_replication_type = "LRS" - - customer_managed_key { - user_assigned_identity_id = "some-id" - } -} \ No newline at end of file From 796472ce7e045c33f35111331948bbbb9371cf11 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:22 +0100 Subject: [PATCH 454/900] fix(queries): remove azure_storage_critical_data_cmk_manual from PR --- .../test/positive_expected_result.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive_expected_result.json diff --git a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive_expected_result.json deleted file mode 100644 index d556848e2e8..00000000000 --- a/assets/queries/terraform/azure/azure_storage_critical_data_cmk_manual/test/positive_expected_result.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "queryName": "Beta - Critical Data Storage CMK (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Beta - Critical Data Storage CMK (Manual)", - "severity": "INFO", - "line": 8, - "fileName": "positive2.tf" - } -] From f3c787639728c819d4cce648e6b9bba9465bfa75 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:24 +0100 Subject: [PATCH 455/900] fix(queries): remove ibm_block_storage_customer_encryption_unified from PR --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json deleted file mode 100644 index 652684418ae..00000000000 --- a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "56cd75da-f919-4350-8b32-1d0e4313e965", - "queryName": "Beta - IBM Block Storage Encryption (CMK/BYOK/KYOK) Manual", - "severity": "INFO", - "category": "Encryption", - "descriptionText": "The Block Storage volume uses default provider-managed encryption. It is not configured with 'encryption_key', which is required for Customer Managed Keys (CMK), Bring Your Own Key (BYOK), or Keep Your Own Key (KYOK). Manual verification of the key source is required.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_volume", - "platform": "Terraform", - "descriptionID": "56cd75da", - "cloudProvider": "ibm", - "cwe": "312", - "riskScore": 0.0, - "experimental": "true" -} \ No newline at end of file From 7eb2c3e55740cdad3ab6b07b4d0d770a69ac8b16 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:24 +0100 Subject: [PATCH 456/900] fix(queries): remove ibm_block_storage_customer_encryption_unified from PR --- .../query.rego | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/query.rego diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/query.rego b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/query.rego deleted file mode 100644 index 690198eefdc..00000000000 --- a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/query.rego +++ /dev/null @@ -1,17 +0,0 @@ -package Cx - -# REGLA UNIFICADA: Cifrado Gestionado por el Cliente en Block Storage. -CxPolicy[result] { - doc := input.document[i] - volume := doc.resource.ibm_is_volume[name] - - object.get(volume, "encryption_key", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_is_volume.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'encryption_key' attribute should be defined (prerequisite for CMK, BYOK, or KYOK)", - "keyActualValue": "'encryption_key' is missing (using default provider-managed encryption)", - } -} \ No newline at end of file From fce688ae521d557171aafb5d686df33b600d54a8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:25 +0100 Subject: [PATCH 457/900] fix(queries): remove ibm_block_storage_customer_encryption_unified from PR --- .../test/negative1.tf | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/negative1.tf diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/negative1.tf b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/negative1.tf deleted file mode 100644 index 8e5181710a7..00000000000 --- a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/negative1.tf +++ /dev/null @@ -1,12 +0,0 @@ -provider "ibm" { - region = "us-south" -} - -resource "ibm_is_volume" "volume_secure" { - name = "secure-volume" - profile = "general-purpose" - zone = "us-south-1" - - # CORRECTO: Se define una clave de cifrado - encryption_key = "crn:v1:bluemix:public:kms:us-south:a/test:test:key:test" -} \ No newline at end of file From 22d6e3bf35ff1aa9bd3200e9c637e26230836aab Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:26 +0100 Subject: [PATCH 458/900] fix(queries): remove ibm_block_storage_customer_encryption_unified from PR --- .../test/positive1.tf | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive1.tf diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive1.tf b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive1.tf deleted file mode 100644 index aa5e37d06c0..00000000000 --- a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive1.tf +++ /dev/null @@ -1,10 +0,0 @@ -provider "ibm" { - region = "us-south" -} - -resource "ibm_is_volume" "volume_insecure" { - name = "insecure-volume" - profile = "general-purpose" - zone = "us-south-1" - # FALLO: Falta el atributo encryption_key -} \ No newline at end of file From 2dc3bcf3b344152927d7d65cb5ea1ebcc7ee5e9d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:27 +0100 Subject: [PATCH 459/900] fix(queries): remove ibm_block_storage_customer_encryption_unified from PR --- .../test/positive_expected_result.json | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive_expected_result.json diff --git a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive_expected_result.json deleted file mode 100644 index 78a823b9db2..00000000000 --- a/assets/queries/terraform/ibm/ibm_block_storage_customer_encryption_unified/test/positive_expected_result.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "queryName": "Beta - IBM Block Storage Encryption (CMK/BYOK/KYOK) Manual", - "severity": "INFO", - "line": 5, - "fileName": "positive1.tf" - } -] From 4219d53b89a115380bd16e834ef3097cbd3cd0fb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:29 +0100 Subject: [PATCH 460/900] fix(queries): remove ibm_cos_bucket_customer_encryption_unified from PR --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json deleted file mode 100644 index 55ca607347d..00000000000 --- a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "8f65bf01-e9e9-4dd6-82b1-67051c2f073d", - "queryName": "Beta - IBM COS Bucket Encryption (CMK/BYOK/KYOK) Manual", - "severity": "INFO", - "category": "Encryption", - "descriptionText": "The Cloud Object Storage bucket relies on default provider-managed encryption. It is not configured with 'key_protect', which is required for Customer Managed Keys (CMK), Bring Your Own Key (BYOK), or Keep Your Own Key (KYOK). Manual verification is required to determine the specific encryption requirement.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/cos_bucket", - "platform": "Terraform", - "descriptionID": "8f65bf01", - "cloudProvider": "ibm", - "cwe": "312", - "riskScore": 0.0, - "experimental": "true" -} \ No newline at end of file From e4db81bd61dd4bbabcbd045930a83b4d4846ddb4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:29 +0100 Subject: [PATCH 461/900] fix(queries): remove ibm_cos_bucket_customer_encryption_unified from PR --- .../query.rego | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/query.rego diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/query.rego b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/query.rego deleted file mode 100644 index 04a56602fc0..00000000000 --- a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/query.rego +++ /dev/null @@ -1,17 +0,0 @@ -package Cx - -# REGLA UNIFICADA: Verificación de Cifrado Gestionado por el Cliente en COS. -CxPolicy[result] { - doc := input.document[i] - bucket := doc.resource.ibm_cos_bucket[name] - - object.get(bucket, "key_protect", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_cos_bucket.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'key_protect' attribute should be defined (required for CMK, BYOK, or KYOK)", - "keyActualValue": "'key_protect' is missing (using default provider-managed encryption)", - } -} \ No newline at end of file From 5ff1bf3df364d94d7d81f7e6abc62652c2127336 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:30 +0100 Subject: [PATCH 462/900] fix(queries): remove ibm_cos_bucket_customer_encryption_unified from PR --- .../test/negative1.tf | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/negative1.tf diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/negative1.tf b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/negative1.tf deleted file mode 100644 index a096fdcc81f..00000000000 --- a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/negative1.tf +++ /dev/null @@ -1,13 +0,0 @@ -provider "ibm" { - region = "us-south" -} - -resource "ibm_cos_bucket" "bucket_secure" { - bucket_name = "secure-bucket" - resource_instance_id = "crn:v1:bluemix:public:cloud-object-storage:..." - storage_class = "standard" - region_location = "us-south" - - # CORRECTO: Se define la clave de cifrado del cliente - key_protect = "crn:v1:bluemix:public:kms:us-south:a/test:test:key:test" -} \ No newline at end of file From e749e18c55900fd1e1146080a0b54f780112ab69 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:31 +0100 Subject: [PATCH 463/900] fix(queries): remove ibm_cos_bucket_customer_encryption_unified from PR --- .../test/positive1.tf | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive1.tf diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive1.tf b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive1.tf deleted file mode 100644 index c71b8b828c4..00000000000 --- a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive1.tf +++ /dev/null @@ -1,11 +0,0 @@ -provider "ibm" { - region = "us-south" -} - -resource "ibm_cos_bucket" "bucket_insecure" { - bucket_name = "insecure-bucket" - resource_instance_id = "crn:v1:bluemix:public:cloud-object-storage:..." - storage_class = "standard" - region_location = "us-south" - # FALLO: Falta el atributo key_protect -} \ No newline at end of file From 4d4718715224bab7390d5444d09478bbe5f7a968 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:31 +0100 Subject: [PATCH 464/900] fix(queries): remove ibm_cos_bucket_customer_encryption_unified from PR --- .../test/positive_expected_result.json | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive_expected_result.json diff --git a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive_expected_result.json b/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive_expected_result.json deleted file mode 100644 index 4084c292010..00000000000 --- a/assets/queries/terraform/ibm/ibm_cos_bucket_customer_encryption_unified/test/positive_expected_result.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "queryName": "Beta - IBM COS Bucket Encryption (CMK/BYOK/KYOK) Manual", - "severity": "INFO", - "line": 5, - "fileName": "positive1.tf" - } -] From 47a95e056cbdf9e265e86745b53d46b8021a2eba Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:33 +0100 Subject: [PATCH 465/900] fix(queries): remove gcp_gke_image_vulnerability_scanning_disabled from PR --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json deleted file mode 100644 index eda1632cb93..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "30b5b4bb-a4dd-41b5-9caf-32e9b017a35e", - "queryName": "Beta - GKE Image Vulnerability Scanning Disabled", - "severity": "HIGH", - "category": "Supply-Chain", - "descriptionText": "Ensures that Image Vulnerability Scanning is enabled in GKE clusters via the security posture configuration. This feature automatically scans workloads for known vulnerabilities.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_cluster#vulnerability_mode", - "platform": "Terraform", - "descriptionID": "30b5b4bb", - "cloudProvider": "gcp", - "cwe": "1395", - "riskScore": "9.0", - "experimental": "true" -} \ No newline at end of file From bdc5c3e6c19a9d2ee0bc8fdd87abcc616631eb89 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:34 +0100 Subject: [PATCH 466/900] fix(queries): remove gcp_gke_image_vulnerability_scanning_disabled from PR --- .../query.rego | 59 ------------------- 1 file changed, 59 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego deleted file mode 100644 index b843d13d5fb..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/query.rego +++ /dev/null @@ -1,59 +0,0 @@ -package Cx - -import data.generic.terraform as tf_lib - -# RULE 1: 'security_posture_config' block missing. -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - not cluster.security_posture_config - - result := { - "documentId": doc.id, - "resourceType": "google_container_cluster", - "resourceName": tf_lib.get_resource_name(cluster, name), - "searchKey": sprintf("google_container_cluster[%s]", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'security_posture_config' block should be defined", - "keyActualValue": "'security_posture_config' block is missing", - } -} - -# RULE 2: 'vulnerability_mode' attribute missing within the block. -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - cluster.security_posture_config - not cluster.security_posture_config.vulnerability_mode - - result := { - "documentId": doc.id, - "resourceType": "google_container_cluster", - "resourceName": tf_lib.get_resource_name(cluster, name), - "searchKey": sprintf("google_container_cluster[%s].security_posture_config", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'vulnerability_mode' should be defined within security_posture_config", - "keyActualValue": "'vulnerability_mode' is missing", - } -} - -# RULE 3: 'vulnerability_mode' attribute configured as 'VULNERABILITY_DISABLED'. -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - mode := cluster.security_posture_config.vulnerability_mode - mode == "VULNERABILITY_DISABLED" - - result := { - "documentId": doc.id, - "resourceType": "google_container_cluster", - "resourceName": tf_lib.get_resource_name(cluster, name), - "searchKey": sprintf("google_container_cluster[%s].security_posture_config.vulnerability_mode", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'vulnerability_mode' should be 'VULNERABILITY_BASIC' or 'VULNERABILITY_ENTERPRISE'", - "keyActualValue": "'vulnerability_mode' is set to 'VULNERABILITY_DISABLED'", - } -} From 3a87423f7e2188950110f0130d9f5778023dc6ad Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:34 +0100 Subject: [PATCH 467/900] fix(queries): remove gcp_gke_image_vulnerability_scanning_disabled from PR --- .../test/negative1.tf | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative1.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative1.tf b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative1.tf deleted file mode 100644 index 59cb11a0bb0..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative1.tf +++ /dev/null @@ -1,8 +0,0 @@ -resource "google_container_cluster" "pass_vulnerability_basic" { - name = "compliant-cluster-basic" - - security_posture_config { - mode = "BASIC" - vulnerability_mode = "VULNERABILITY_BASIC" - } -} \ No newline at end of file From f91c355ccdd291001e196b5d028e43c3cf973f7e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:35 +0100 Subject: [PATCH 468/900] fix(queries): remove gcp_gke_image_vulnerability_scanning_disabled from PR --- .../test/negative2.tf | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative2.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative2.tf b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative2.tf deleted file mode 100644 index ed4e5fdb59b..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/negative2.tf +++ /dev/null @@ -1,8 +0,0 @@ -resource "google_container_cluster" "pass_vulnerability_enterprise" { - name = "compliant-cluster-enterprise" - - security_posture_config { - mode = "ENTERPRISE" - vulnerability_mode = "VULNERABILITY_ENTERPRISE" - } -} \ No newline at end of file From 2d0eda1a7d9e2877959732c7f85e847f7767e1a4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:36 +0100 Subject: [PATCH 469/900] fix(queries): remove gcp_gke_image_vulnerability_scanning_disabled from PR --- .../test/positive1.tf | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive1.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive1.tf deleted file mode 100644 index 47c80cdd8b0..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive1.tf +++ /dev/null @@ -1,5 +0,0 @@ -resource "google_container_cluster" "fail_block_missing" { - name = "no-security-config" - location = "us-central1" - # Fallo: No existe el bloque de postura de seguridad -} \ No newline at end of file From b24e31b0103ae8f3b643328dae9717855564beac Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:37 +0100 Subject: [PATCH 470/900] fix(queries): remove gcp_gke_image_vulnerability_scanning_disabled from PR --- .../test/positive2.tf | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive2.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive2.tf deleted file mode 100644 index fff3f5bf020..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive2.tf +++ /dev/null @@ -1,8 +0,0 @@ -resource "google_container_cluster" "fail_attr_missing" { - name = "partial-security-config" - - security_posture_config { - mode = "BASIC" - # Fallo: Falta definir vulnerability_mode dentro del bloque - } -} \ No newline at end of file From 72f9512ab9efec09bb00f8199236b2fa39fe0540 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:37 +0100 Subject: [PATCH 471/900] fix(queries): remove gcp_gke_image_vulnerability_scanning_disabled from PR --- .../test/positive3.tf | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive3.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive3.tf b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive3.tf deleted file mode 100644 index cf0bab1c4d3..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive3.tf +++ /dev/null @@ -1,8 +0,0 @@ -resource "google_container_cluster" "fail_mode_disabled" { - name = "disabled-scanning-cluster" - - security_posture_config { - mode = "BASIC" - vulnerability_mode = "VULNERABILITY_DISABLED" # Fallo: Deshabilitado - } -} \ No newline at end of file From 96b0d8dcf94a00209e0d34802cf81bb2b0b33341 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:38 +0100 Subject: [PATCH 472/900] fix(queries): remove gcp_gke_image_vulnerability_scanning_disabled from PR --- .../test/positive_expected_result.json | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive_expected_result.json diff --git a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive_expected_result.json deleted file mode 100644 index 56713472795..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_image_vulnerability_scanning_disabled/test/positive_expected_result.json +++ /dev/null @@ -1,20 +0,0 @@ -[ - { - "queryName": "Beta - GKE Image Vulnerability Scanning Disabled", - "severity": "HIGH", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Beta - GKE Image Vulnerability Scanning Disabled", - "severity": "HIGH", - "line": 4, - "fileName": "positive2.tf" - }, - { - "queryName": "Beta - GKE Image Vulnerability Scanning Disabled", - "severity": "HIGH", - "line": 6, - "fileName": "positive3.tf" - } -] From 46c740d535253500f967a6c8668ebe54206d1475 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:40 +0100 Subject: [PATCH 473/900] fix(queries): remove gcp_gke_security_posture_manual from PR --- .../gcp_gke_security_posture_manual/metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json deleted file mode 100644 index 21b2cb79fb2..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "0d688e9b-79a1-4adb-8893-4cae93442ffd", - "queryName": "Beta - GKE Security Posture Disabled (Manual)", - "severity": "INFO", - "category": "Observability", - "descriptionText": "GKE Security Posture Dashboard provides visibility into the security status of the cluster. It is not explicitly enabled. Verify if the cluster version supports 'security_posture_config' with mode 'BASIC' or 'ENTERPRISE'.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_cluster#security_posture_config", - "platform": "Terraform", - "descriptionID": "0d688e9b", - "cloudProvider": "gcp", - "cwe": "1038", - "riskScore": "0.0", - "experimental": "true" -} \ No newline at end of file From 611dc2e9db3a24c6488d43b93ef33a0267bdbf89 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:41 +0100 Subject: [PATCH 474/900] fix(queries): remove gcp_gke_security_posture_manual from PR --- .../query.rego | 39 ------------------- 1 file changed, 39 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego deleted file mode 100644 index 86c17a5454d..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/query.rego +++ /dev/null @@ -1,39 +0,0 @@ -package Cx - -import data.generic.terraform as tf_lib - -# RULE 1: 'security_posture_config' block missing. -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - not cluster.security_posture_config - - result := { - "documentId": doc.id, - "resourceType": "google_container_cluster", - "resourceName": tf_lib.get_resource_name(cluster, name), - "searchKey": sprintf("google_container_cluster[%s]", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'security_posture_config' block should be defined with mode 'BASIC' or 'ENTERPRISE'", - "keyActualValue": "'security_posture_config' block is missing", - } -} - -# RULE 2: Block present, but 'mode' is 'DISABLED'. -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.google_container_cluster[name] - - cluster.security_posture_config.mode == "DISABLED" - - result := { - "documentId": doc.id, - "resourceType": "google_container_cluster", - "resourceName": tf_lib.get_resource_name(cluster, name), - "searchKey": sprintf("google_container_cluster[%s].security_posture_config.mode", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'mode' should be set to 'BASIC' or 'ENTERPRISE'", - "keyActualValue": "'mode' is set to 'DISABLED'", - } -} From c5c2aa16576188b6c5ec4aab9b9d6fcd48d61933 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:42 +0100 Subject: [PATCH 475/900] fix(queries): remove gcp_gke_security_posture_manual from PR --- .../gcp/gcp_gke_security_posture_manual/test/negative1.tf | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative1.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative1.tf b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative1.tf deleted file mode 100644 index 22015e1b111..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative1.tf +++ /dev/null @@ -1,6 +0,0 @@ -resource "google_container_cluster" "pass_basic" { - name = "secure-cluster-basic" - security_posture_config { - mode = "BASIC" - } -} \ No newline at end of file From d9691a5d88504fd048bab7d0c92e0499ee643260 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:42 +0100 Subject: [PATCH 476/900] fix(queries): remove gcp_gke_security_posture_manual from PR --- .../gcp/gcp_gke_security_posture_manual/test/negative2.tf | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative2.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative2.tf b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative2.tf deleted file mode 100644 index efe51b91f0f..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/negative2.tf +++ /dev/null @@ -1,6 +0,0 @@ -resource "google_container_cluster" "pass_enterprise" { - name = "secure-cluster-enterprise" - security_posture_config { - mode = "ENTERPRISE" - } -} \ No newline at end of file From dc395e4d5e513b3d0ff0a2f6d226b410e3ef842b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:43 +0100 Subject: [PATCH 477/900] fix(queries): remove gcp_gke_security_posture_manual from PR --- .../gcp/gcp_gke_security_posture_manual/test/positive1.tf | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive1.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive1.tf deleted file mode 100644 index 9fef725d35d..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive1.tf +++ /dev/null @@ -1,5 +0,0 @@ -resource "google_container_cluster" "fail_block_missing" { - name = "cluster-without-posture" - location = "us-central1" - # FALLO: Falta security_posture_config -} \ No newline at end of file From 315993c90046be9cab2178925f9f4be29d254b7a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:44 +0100 Subject: [PATCH 478/900] fix(queries): remove gcp_gke_security_posture_manual from PR --- .../gcp/gcp_gke_security_posture_manual/test/positive2.tf | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive2.tf diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive2.tf deleted file mode 100644 index 07f2184f850..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive2.tf +++ /dev/null @@ -1,7 +0,0 @@ -resource "google_container_cluster" "fail_mode_disabled" { - name = "cluster-posture-off" - - security_posture_config { - mode = "DISABLED" # FALLO: Debe ser BASIC o ENTERPRISE - } -} \ No newline at end of file From c2a52ef36d65dd66978e416f943ba738e7d4b877 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:45 +0100 Subject: [PATCH 479/900] fix(queries): remove gcp_gke_security_posture_manual from PR --- .../test/positive_expected_result.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive_expected_result.json diff --git a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive_expected_result.json deleted file mode 100644 index 5cd5538234d..00000000000 --- a/assets/queries/terraform/gcp/gcp_gke_security_posture_manual/test/positive_expected_result.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "queryName": "Beta - GKE Security Posture Disabled (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Beta - GKE Security Posture Disabled (Manual)", - "severity": "INFO", - "line": 5, - "fileName": "positive2.tf" - } -] From 445724511029ffdb0841805fe7e4a4ee305c5bd8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:47 +0100 Subject: [PATCH 480/900] fix(queries): remove azure_backup_vault_cmk_encryption_disabled from PR --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json deleted file mode 100644 index 14e4d9cb01c..00000000000 --- a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "bf4474a7-7495-4292-af22-a97c1cc95d2b", - "queryName": "Beta - Backup Vault CMK Encryption Disabled", - "severity": "MEDIUM", - "category": "Encryption", - "descriptionText": "Ensures that Azure Backup Vaults (Data Protection) are encrypted using Customer-Managed Keys (CMK) stored in Azure Key Vault, instead of platform-managed keys.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/data_protection_backup_vault_customer_managed_key", - "platform": "Terraform", - "descriptionID": "bf4474a7", - "cloudProvider": "azure", - "cwe": "326", - "riskScore": "5.0", - "experimental": "true" -} \ No newline at end of file From 78058ee09be9becdd37a49dc163be96a92bdb8b1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:48 +0100 Subject: [PATCH 481/900] fix(queries): remove azure_backup_vault_cmk_encryption_disabled from PR --- .../query.rego | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego deleted file mode 100644 index 5be62a40e54..00000000000 --- a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/query.rego +++ /dev/null @@ -1,29 +0,0 @@ -package Cx - -import data.generic.terraform as tf_lib - -has_cmk_configured(doc, vault_id) { - cmk := doc.resource.azurerm_data_protection_backup_vault_customer_managed_key[_] - cmk.data_protection_backup_vault_id == vault_id - cmk.key_vault_key_id -} - -# RULE 1: The Backup Vault does not have CMK encryption configured through the association resource. -CxPolicy[result] { - doc := input.document[i] - vault := doc.resource.azurerm_data_protection_backup_vault[name] - - vault_id := sprintf("${azurerm_data_protection_backup_vault.%s.id}", [name]) - - not has_cmk_configured(doc, vault_id) - - result := { - "documentId": doc.id, - "resourceType": "azurerm_data_protection_backup_vault", - "resourceName": tf_lib.get_resource_name(vault, name), - "searchKey": sprintf("azurerm_data_protection_backup_vault[%s]", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should be associated with an 'azurerm_data_protection_backup_vault_customer_managed_key' resource", [name]), - "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is using Platform-Managed Keys (default)", [name]), - } -} From 9006ebb244efe7879d5b2128f984d9b954a080d8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:48 +0100 Subject: [PATCH 482/900] fix(queries): remove azure_backup_vault_cmk_encryption_disabled from PR --- .../test/negative1.tf | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/negative1.tf diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/negative1.tf deleted file mode 100644 index 8c6778ce2a1..00000000000 --- a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/negative1.tf +++ /dev/null @@ -1,16 +0,0 @@ -resource "azurerm_data_protection_backup_vault" "pass_vault" { - name = "backup-vault-secure" - resource_group_name = "rg-backup" - location = "East US" - datastore_type = "VaultStore" - redundancy = "LocallyRedundant" - - identity { - type = "SystemAssigned" - } -} - -resource "azurerm_data_protection_backup_vault_customer_managed_key" "pass_cmk" { - data_protection_backup_vault_id = azurerm_data_protection_backup_vault.pass_vault.id - key_vault_key_id = "https://example-kv.vault.azure.net/keys/example-key/version" -} \ No newline at end of file From 4f367c3fe9cbb2ee11c69fe44354329b3cf79c6c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:49 +0100 Subject: [PATCH 483/900] fix(queries): remove azure_backup_vault_cmk_encryption_disabled from PR --- .../test/positive1.tf | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive1.tf diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive1.tf deleted file mode 100644 index d9b59238be8..00000000000 --- a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive1.tf +++ /dev/null @@ -1,11 +0,0 @@ -resource "azurerm_data_protection_backup_vault" "fail_vault" { - name = "backup-vault-insecure" - resource_group_name = "rg-backup" - location = "East US" - datastore_type = "VaultStore" - redundancy = "LocallyRedundant" - - identity { - type = "SystemAssigned" - } -} \ No newline at end of file From c60a0126b0f91b0c1379e978fb44f05ddc5251c4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:50 +0100 Subject: [PATCH 484/900] fix(queries): remove azure_backup_vault_cmk_encryption_disabled from PR --- .../test/positive_expected_result.json | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive_expected_result.json diff --git a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive_expected_result.json deleted file mode 100644 index f8491137b15..00000000000 --- a/assets/queries/terraform/azure/azure_backup_vault_cmk_encryption_disabled/test/positive_expected_result.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "queryName": "Beta - Backup Vault CMK Encryption Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] From 29da8db7615197c0cae7eb5a1231bc8d88a9dcb0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:52 +0100 Subject: [PATCH 485/900] fix(queries): remove azure_sql_server_tde_cmk_disabled from PR --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json deleted file mode 100644 index 6344d1db3e9..00000000000 --- a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "745e82b3-edf5-4606-a5c2-25d8453e7de6", - "queryName": "Beta - SQL Server TDE Not Encrypted with CMK", - "severity": "MEDIUM", - "category": "Encryption", - "descriptionText": "Ensures that Azure SQL Server Transparent Data Encryption (TDE) is configured with a Customer-Managed Key (CMK) stored in Azure Key Vault, rather than the default Service-Managed Key.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/mssql_server_transparent_data_encryption", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "326", - "descriptionID": "745e82b3", - "riskScore": "5.0", - "experimental": "true" -} \ No newline at end of file From 7b6deb48b5d5f42166da1a400ed263e9dbb8f292 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:52 +0100 Subject: [PATCH 486/900] fix(queries): remove azure_sql_server_tde_cmk_disabled from PR --- .../query.rego | 36 ------------------- 1 file changed, 36 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego deleted file mode 100644 index 519e0fc388d..00000000000 --- a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/query.rego +++ /dev/null @@ -1,36 +0,0 @@ -package Cx - -import data.generic.terraform as tf_lib - -has_cmk_tde(doc, server_id) { - tde := doc.resource.azurerm_mssql_server_transparent_data_encryption[_] - check_id(tde.server_id, server_id) - tde.key_vault_key_id -} - -check_id(current, target) { - current == target -} - -check_id(current, target) { - current == sprintf("${%s}", [target]) -} - -# RULE 1: SQL Server without explicit TDE configuration or without CMK. -CxPolicy[result] { - doc := input.document[i] - server := doc.resource.azurerm_mssql_server[name] - server_id := sprintf("azurerm_mssql_server.%s.id", [name]) - - not has_cmk_tde(doc, server_id) - - result := { - "documentId": doc.id, - "resourceType": "azurerm_mssql_server", - "resourceName": tf_lib.get_resource_name(server, name), - "searchKey": sprintf("azurerm_mssql_server[%s]", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_mssql_server.%s' should have an associated 'azurerm_mssql_server_transparent_data_encryption' resource with 'key_vault_key_id' set", [name]), - "keyActualValue": sprintf("'azurerm_mssql_server.%s' is using Service-Managed Key (default) or lacks TDE resource", [name]), - } -} From c4af3bf3b8f6f41f4cf98e5efdf371283996f023 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:53 +0100 Subject: [PATCH 487/900] fix(queries): remove azure_sql_server_tde_cmk_disabled from PR --- .../test/negative1.tf | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/negative1.tf diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/negative1.tf deleted file mode 100644 index 9d1a96c6668..00000000000 --- a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/negative1.tf +++ /dev/null @@ -1,13 +0,0 @@ -resource "azurerm_mssql_server" "pass" { - name = "sql-server-pass" - resource_group_name = "rg-test" - location = "West Europe" - version = "12.0" - administrator_login = "sqladmin" - administrator_login_password = "Password123!" -} - -resource "azurerm_mssql_server_transparent_data_encryption" "pass_tde" { - server_id = azurerm_mssql_server.pass.id - key_vault_key_id = "https://kv.vault.azure.net/keys/key/v1" -} \ No newline at end of file From 1b11de7f99e695fc7499fbb3da19f5f3ef869560 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:54 +0100 Subject: [PATCH 488/900] fix(queries): remove azure_sql_server_tde_cmk_disabled from PR --- .../azure_sql_server_tde_cmk_disabled/test/positive1.tf | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive1.tf diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive1.tf deleted file mode 100644 index 7e5a913fb3e..00000000000 --- a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive1.tf +++ /dev/null @@ -1,8 +0,0 @@ -resource "azurerm_mssql_server" "fail" { - name = "sql-server-fail" - resource_group_name = "rg-test" - location = "West Europe" - version = "12.0" - administrator_login = "sqladmin" - administrator_login_password = "Password123!" -} \ No newline at end of file From 109e00a62f174235ccae5cbb33dabc62380ed0f8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:54 +0100 Subject: [PATCH 489/900] fix(queries): remove azure_sql_server_tde_cmk_disabled from PR --- .../test/positive_expected_result.json | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive_expected_result.json diff --git a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive_expected_result.json deleted file mode 100644 index cdd71bd7acf..00000000000 --- a/assets/queries/terraform/azure/azure_sql_server_tde_cmk_disabled/test/positive_expected_result.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "queryName": "Beta - SQL Server TDE Not Encrypted with CMK", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] From f7507b340c7a87dbe8e85db099cd1327de280083 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:56 +0100 Subject: [PATCH 490/900] fix(queries): remove azure_netapp_account_cmk_encryption_disabled from PR --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json deleted file mode 100644 index cbe01d8b44d..00000000000 --- a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "8bed44b5-bcd6-42f4-b7b6-f59fd4edc94a", - "queryName": "Beta - NetApp Account CMK Encryption Disabled", - "severity": "MEDIUM", - "category": "Encryption", - "descriptionText": "Ensures that Azure NetApp Files accounts are configured to use Customer-Managed Keys (CMK) for encryption, instead of the default platform-managed keys.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/netapp_account_encryption", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "326", - "descriptionID": "8bed44b5", - "riskScore": "5.0", - "experimental": "true" -} \ No newline at end of file From 86d72c9cd0b902edeeff629197c395c7f790c5ab Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:57 +0100 Subject: [PATCH 491/900] fix(queries): remove azure_netapp_account_cmk_encryption_disabled from PR --- .../query.rego | 40 ------------------- 1 file changed, 40 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego deleted file mode 100644 index 4965d4fde46..00000000000 --- a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/query.rego +++ /dev/null @@ -1,40 +0,0 @@ -package Cx - -import data.generic.terraform as tf_lib - -has_encryption_resource(doc, account_id) { - enc := doc.resource.azurerm_netapp_account_encryption[_] - check_id(enc.netapp_account_id, account_id) -} - -check_id(current, target) { - current == target -} - -check_id(current, target) { - current == sprintf("${%s}", [target]) -} - -has_inline_encryption(account) { - account.encryption.key_source == "Microsoft.KeyVault" -} - -# RULE 1: The NetApp account uses Platform-Managed Keys (CMK configuration is missing). -CxPolicy[result] { - doc := input.document[i] - account := doc.resource.azurerm_netapp_account[name] - account_id := sprintf("azurerm_netapp_account.%s.id", [name]) - - not has_inline_encryption(account) - not has_encryption_resource(doc, account_id) - - result := { - "documentId": doc.id, - "resourceType": "azurerm_netapp_account", - "resourceName": tf_lib.get_resource_name(account, name), - "searchKey": sprintf("azurerm_netapp_account[%s]", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_netapp_account.%s' should have 'encryption.key_source' set to 'Microsoft.KeyVault' or have an 'azurerm_netapp_account_encryption' resource associated", [name]), - "keyActualValue": sprintf("'azurerm_netapp_account.%s' is using Platform-Managed Keys (default)", [name]), - } -} From fbf4bb45510ec5d5ee027d7306af48d6439c9620 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:58 +0100 Subject: [PATCH 492/900] fix(queries): remove azure_netapp_account_cmk_encryption_disabled from PR --- .../test/negative1.tf | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/negative1.tf diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/negative1.tf deleted file mode 100644 index 610c7e965bf..00000000000 --- a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/negative1.tf +++ /dev/null @@ -1,16 +0,0 @@ -resource "azurerm_netapp_account" "pass" { - name = "pass-netapp" - resource_group_name = "rg-example" - location = "West Europe" - - identity { - type = "UserAssigned" - identity_ids = ["/subscriptions/000/resourceGroups/rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id"] - } -} - -resource "azurerm_netapp_account_encryption" "pass_encryption" { - netapp_account_id = azurerm_netapp_account.pass.id - user_assigned_identity_id = "/subscriptions/000/resourceGroups/rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id" - encryption_key = "https://kv.vault.azure.net/keys/key/v1" -} \ No newline at end of file From f9c660465bfe5511718ae339d5faf5284573fb05 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:58 +0100 Subject: [PATCH 493/900] fix(queries): remove azure_netapp_account_cmk_encryption_disabled from PR --- .../test/positive1.tf | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive1.tf diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive1.tf deleted file mode 100644 index 76a7edb055f..00000000000 --- a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive1.tf +++ /dev/null @@ -1,5 +0,0 @@ -resource "azurerm_netapp_account" "fail" { - name = "fail-netapp" - resource_group_name = "rg-example" - location = "West Europe" -} \ No newline at end of file From 5d88c9b5f1868b115c88961cd3592b0b0fcee2e4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:18:59 +0100 Subject: [PATCH 494/900] fix(queries): remove azure_netapp_account_cmk_encryption_disabled from PR --- .../test/positive_expected_result.json | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive_expected_result.json diff --git a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive_expected_result.json deleted file mode 100644 index 60253e45ad4..00000000000 --- a/assets/queries/terraform/azure/azure_netapp_account_cmk_encryption_disabled/test/positive_expected_result.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "queryName": "Beta - NetApp Account CMK Encryption Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] From 7676bdaf0f7e20490fe93126189a8ed611a9e559 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:00 +0100 Subject: [PATCH 495/900] fix(queries): remove azure_elastic_san_volume_group_cmk_encryption_disabled from PR --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json deleted file mode 100644 index e7a30ea9bf0..00000000000 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "3b101ad5-3602-4a9e-b6ca-16b7b31b153c", - "queryName": "Beta - Elastic SAN Volume Group CMK Encryption Disabled", - "severity": "MEDIUM", - "category": "Encryption", - "descriptionText": "Ensures that Azure Elastic SAN Volume Groups are encrypted using Customer-Managed Keys (CMK). Using CMK provides control over key lifecycle and access policies, unlike the default platform-managed keys.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/elastic_san_volume_group#encryption_type", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "326", - "descriptionID": "3b101ad5", - "riskScore": "5.0", - "experimental": "true" -} \ No newline at end of file From 1c77f0c30707cf48517e807814215c3cf2254097 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:01 +0100 Subject: [PATCH 496/900] fix(queries): remove azure_elastic_san_volume_group_cmk_encryption_disabled from PR --- .../query.rego | 44 ------------------- 1 file changed, 44 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego deleted file mode 100644 index b83ba1e8b05..00000000000 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/query.rego +++ /dev/null @@ -1,44 +0,0 @@ -package Cx - -import data.generic.terraform as tf_lib - -# RULE 1: The encryption type is not CMK or is not defined. -CxPolicy[result] { - doc := input.document[i] - vg := doc.resource.azurerm_elastic_san_volume_group[name] - - object.get(vg, "encryption_type", "undefined") != "EncryptionAtRestWithCustomerManagedKey" - - result := { - "documentId": doc.id, - "resourceType": "azurerm_elastic_san_volume_group", - "resourceName": tf_lib.get_resource_name(vg, name), - "searchKey": sprintf("azurerm_elastic_san_volume_group[%s]", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'encryption_type' should be set to 'EncryptionAtRestWithCustomerManagedKey'", - "keyActualValue": sprintf("'encryption_type' is set to '%v'", [object.get(vg, "encryption_type", "PlatformKey (Default)")]), - } -} - -# RULE 2: If the type is CMK, both the 'encryption' block and the 'identity' block must exist. -CxPolicy[result] { - doc := input.document[i] - vg := doc.resource.azurerm_elastic_san_volume_group[name] - vg.encryption_type == "EncryptionAtRestWithCustomerManagedKey" - - required_blocks := {"encryption", "identity"} - existing_blocks := {b | vg[b]} - missing := required_blocks - existing_blocks - - count(missing) > 0 - - result := { - "documentId": doc.id, - "resourceType": "azurerm_elastic_san_volume_group", - "resourceName": tf_lib.get_resource_name(vg, name), - "searchKey": sprintf("azurerm_elastic_san_volume_group[%s]", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_elastic_san_volume_group.%s' should have both 'encryption' and 'identity' blocks for CMK", [name]), - "keyActualValue": sprintf("'azurerm_elastic_san_volume_group.%s' is missing the following block(s): %s", [name, concat(", ", missing)]), - } -} From e3e4002709ba391ff930557afd63efe74956ed09 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:02 +0100 Subject: [PATCH 497/900] fix(queries): remove azure_elastic_san_volume_group_cmk_encryption_disabled from PR --- .../test/negative1.tf | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/negative1.tf diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/negative1.tf deleted file mode 100644 index b7475da1de0..00000000000 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/negative1.tf +++ /dev/null @@ -1,14 +0,0 @@ -resource "azurerm_elastic_san_volume_group" "pass" { - name = "secure-vg" - elastic_san_id = "san-id" - encryption_type = "EncryptionAtRestWithCustomerManagedKey" - - encryption { - key_vault_key_id = "https://kv.vault.azure.net/keys/key/v1" - } - - identity { - type = "UserAssigned" - identity_ids = ["managed_id"] - } -} \ No newline at end of file From 6a9d7833fa7c1e26420dcc86d1149277d027f651 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:03 +0100 Subject: [PATCH 498/900] fix(queries): remove azure_elastic_san_volume_group_cmk_encryption_disabled from PR --- .../test/positive1.tf | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive1.tf diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive1.tf deleted file mode 100644 index a3a7012a077..00000000000 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive1.tf +++ /dev/null @@ -1,5 +0,0 @@ -resource "azurerm_elastic_san_volume_group" "fail_type" { - name = "vg-fail-type" - elastic_san_id = "san-id" - # Falla por no tener encryption_type CMK -} \ No newline at end of file From 7a8bfc8b3d75b2dc4ac924109c0979e326c629d0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:03 +0100 Subject: [PATCH 499/900] fix(queries): remove azure_elastic_san_volume_group_cmk_encryption_disabled from PR --- .../test/positive2.tf | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive2.tf diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive2.tf deleted file mode 100644 index 8eb87a597a9..00000000000 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive2.tf +++ /dev/null @@ -1,6 +0,0 @@ -resource "azurerm_elastic_san_volume_group" "fail_blocks" { - name = "vg-fail-blocks" - elastic_san_id = "san-id" - encryption_type = "EncryptionAtRestWithCustomerManagedKey" - # Falla por faltar bloques encryption e identity -} \ No newline at end of file From 231dc3f0b60e74125611a86e718f6efeaf28e35b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:04 +0100 Subject: [PATCH 500/900] fix(queries): remove azure_elastic_san_volume_group_cmk_encryption_disabled from PR --- .../test/positive_expected_result.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json diff --git a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json deleted file mode 100644 index 97e9d3cbcfd..00000000000 --- a/assets/queries/terraform/azure/azure_elastic_san_volume_group_cmk_encryption_disabled/test/positive_expected_result.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "queryName": "Beta - Elastic SAN Volume Group CMK Encryption Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Beta - Elastic SAN Volume Group CMK Encryption Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive2.tf" - } -] From 2d3be72dd725be63474851217667b6867899b0ac Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:06 +0100 Subject: [PATCH 501/900] fix(queries): remove azure_recovery_services_vault_cmk_encryption_disabled from PR --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json deleted file mode 100644 index 47d682dbf80..00000000000 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "9436d439-99f6-4f81-bef2-e7f50d24d453", - "queryName": "Beta - Recovery Services Vault CMK Encryption Disabled", - "severity": "MEDIUM", - "category": "Encryption", - "descriptionText": "Ensures that Azure Recovery Services Vaults are encrypted using Customer-Managed Keys (CMK) stored in Azure Key Vault. Using CMK provides control over key lifecycle and access policies, unlike the default platform-managed keys.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/recovery_services_vault#encryption", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "326", - "descriptionID": "9436d439", - "riskScore": "5.0", - "experimental": "true" -} \ No newline at end of file From e839c87f64e3f06f5f6061e820141d20a2597905 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:06 +0100 Subject: [PATCH 502/900] fix(queries): remove azure_recovery_services_vault_cmk_encryption_disabled from PR --- .../query.rego | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego deleted file mode 100644 index bfba3322f73..00000000000 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/query.rego +++ /dev/null @@ -1,21 +0,0 @@ -package Cx - -import data.generic.terraform as tf_lib - -# RULE 1: The encryption block is not defined. -CxPolicy[result] { - doc := input.document[i] - vault := doc.resource.azurerm_recovery_services_vault[name] - - not vault.encryption - - result := { - "documentId": doc.id, - "resourceType": "azurerm_recovery_services_vault", - "resourceName": tf_lib.get_resource_name(vault, name), - "searchKey": sprintf("azurerm_recovery_services_vault[%s]", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_recovery_services_vault.%s' should have an 'encryption' block defined with a valid 'key_id'", [name]), - "keyActualValue": sprintf("'azurerm_recovery_services_vault.%s' is missing the 'encryption' block (Platform-Managed Keys by default)", [name]), - } -} From 7537a843d725dd7fcd0f86c8e02f86a878a28ebe Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:07 +0100 Subject: [PATCH 503/900] fix(queries): remove azure_recovery_services_vault_cmk_encryption_disabled from PR --- .../test/negative1.tf | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/negative1.tf diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/negative1.tf deleted file mode 100644 index 3469d90f314..00000000000 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/negative1.tf +++ /dev/null @@ -1,16 +0,0 @@ -resource "azurerm_recovery_services_vault" "pass" { - name = "vault-pass" - location = "West Europe" - resource_group_name = "rg-test" - sku = "Standard" - - identity { - type = "SystemAssigned" - } - - encryption { - key_id = "https://kv.vault.azure.net/keys/key/v1" - infrastructure_encryption_enabled = true - use_system_assigned_identity = true - } -} \ No newline at end of file From 5964b6012639f814d6bac75304cc229c0fdf48ef Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:08 +0100 Subject: [PATCH 504/900] fix(queries): remove azure_recovery_services_vault_cmk_encryption_disabled from PR --- .../test/positive1.tf | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive1.tf diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive1.tf deleted file mode 100644 index 8f2bb000720..00000000000 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive1.tf +++ /dev/null @@ -1,7 +0,0 @@ -resource "azurerm_recovery_services_vault" "fail" { - name = "vault-fail" - location = "West Europe" - resource_group_name = "rg-test" - sku = "Standard" - # Falla por ausencia de bloque encryption -} \ No newline at end of file From 35d1b11ea398bdf80295755890c830f552ae7ce5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:09 +0100 Subject: [PATCH 505/900] fix(queries): remove azure_recovery_services_vault_cmk_encryption_disabled from PR --- .../test/positive_expected_result.json | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive_expected_result.json diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive_expected_result.json deleted file mode 100644 index 1e8483eb9e0..00000000000 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cmk_encryption_disabled/test/positive_expected_result.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "queryName": "Beta - Recovery Services Vault CMK Encryption Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - } -] From 2f3b612f436728aeb105fd2cea19d1e218ccf460 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:10 +0100 Subject: [PATCH 506/900] fix(queries): remove oci_storage_cmk_encryption_unified from PR --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json deleted file mode 100644 index 9849bf1dba5..00000000000 --- a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "cb72ae80-1b5a-407e-9f5b-86ddd64df644", - "queryName": "Beta - OCI Storage Resources Without CMK", - "severity": "MEDIUM", - "category": "Encryption", - "descriptionText": "Storage resources (Object Storage, Block Volumes, Boot Volumes, File Storage) are using default Oracle-managed encryption keys. To satisfy strict compliance requirements, they should be encrypted with a Customer Managed Key (CMK) by defining the 'kms_key_id' attribute.", - "descriptionUrl": "https://docs.oracle.com/en-us/iaas/Content/KeyManagement/Concepts/keyoverview.htm", - "platform": "Terraform", - "descriptionID": "cb72ae80", - "cloudProvider": "oci", - "cwe": "312", - "riskScore": 3.0, - "experimental": "true" -} \ No newline at end of file From d8635bed3b60e13e6b88e150ec23ac09e9f6f993 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:11 +0100 Subject: [PATCH 507/900] fix(queries): remove oci_storage_cmk_encryption_unified from PR --- .../query.rego | 44 ------------------- 1 file changed, 44 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/query.rego diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/query.rego b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/query.rego deleted file mode 100644 index fcfae666d27..00000000000 --- a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/query.rego +++ /dev/null @@ -1,44 +0,0 @@ -package Cx - -targets := { - "oci_objectstorage_bucket", - "oci_core_volume", - "oci_core_boot_volume", - "oci_file_storage_file_system" -} - -# CASO 1: Falta el atributo kms_key_id (Usa claves gestionadas por Oracle) -CxPolicy[result] { - doc := input.document[i] - - resource := doc.resource[resource_type][name] - targets[resource_type] - - object.get(resource, "kms_key_id", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.%s.%s", [resource_type, name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'%s' should have 'kms_key_id' defined with a Vault Key OCID", [name]), - "keyActualValue": "'kms_key_id' is missing (using Oracle-managed keys)", - } -} - -# CASO 2: El atributo existe pero está vacío -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource[resource_type][name] - targets[resource_type] - - resource.kms_key_id - resource.kms_key_id == "" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.%s.%s.kms_key_id", [resource_type, name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'kms_key_id' should not be empty", - "keyActualValue": "'kms_key_id' is empty", - } -} \ No newline at end of file From dd55a26552e291e26534edc70c4a2711e7882520 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:12 +0100 Subject: [PATCH 508/900] fix(queries): remove oci_storage_cmk_encryption_unified from PR --- .../test/negative1.tf | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative1.tf diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative1.tf b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative1.tf deleted file mode 100644 index b55fff6f8b0..00000000000 --- a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative1.tf +++ /dev/null @@ -1,11 +0,0 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_objectstorage_bucket" "bucket_with_cmk" { - compartment_id = "ocid1.compartment.oc1..aaaa" - namespace = "my-namespace" - name = "bucket-secure" - - kms_key_id = "ocid1.key.oc1.iad.example" -} \ No newline at end of file From 9f98bb1b549b68325d7beb4d4ad259d56c97711f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:12 +0100 Subject: [PATCH 509/900] fix(queries): remove oci_storage_cmk_encryption_unified from PR --- .../test/negative2.tf | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative2.tf diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative2.tf b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative2.tf deleted file mode 100644 index 56f1735388d..00000000000 --- a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/negative2.tf +++ /dev/null @@ -1,11 +0,0 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_file_storage_file_system" "fs_secure" { - availability_domain = "AD-1" - compartment_id = "ocid1.compartment.oc1..aaaa" - display_name = "fs-secure" - - kms_key_id = "ocid1.key.oc1.iad.example" -} \ No newline at end of file From b8b3a4f296d6bc2cc30ff87f634dfae87faa9119 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:13 +0100 Subject: [PATCH 510/900] fix(queries): remove oci_storage_cmk_encryption_unified from PR --- .../oci_storage_cmk_encryption_unified/test/positive1.tf | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive1.tf diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive1.tf b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive1.tf deleted file mode 100644 index bee43bee98a..00000000000 --- a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive1.tf +++ /dev/null @@ -1,9 +0,0 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_objectstorage_bucket" "bucket_without_cmk" { - compartment_id = "ocid1.compartment.oc1..aaaa" - namespace = "my-namespace" - name = "bucket-insecure" -} \ No newline at end of file From 14f5c9a611e3fe752d12a982eb452a2501fb2eb0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:14 +0100 Subject: [PATCH 511/900] fix(queries): remove oci_storage_cmk_encryption_unified from PR --- .../test/positive2.tf | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive2.tf diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive2.tf b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive2.tf deleted file mode 100644 index a9c46eafb79..00000000000 --- a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive2.tf +++ /dev/null @@ -1,11 +0,0 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_core_volume" "volume_empty_cmk" { - availability_domain = "AD-1" - compartment_id = "ocid1.compartment.oc1..aaaa" - display_name = "volume-empty" - - kms_key_id = "" -} \ No newline at end of file From 1178d3113976f7811d30fc7a9eba4175b9184734 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:14 +0100 Subject: [PATCH 512/900] fix(queries): remove oci_storage_cmk_encryption_unified from PR --- .../test/positive_expected_result.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive_expected_result.json diff --git a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive_expected_result.json deleted file mode 100644 index 7da1b413ab4..00000000000 --- a/assets/queries/terraform/oci/oci_storage_cmk_encryption_unified/test/positive_expected_result.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "queryName": "Beta - OCI Storage Resources Without CMK", - "severity": "MEDIUM", - "line": 5, - "fileName": "positive1.tf" - }, - { - "queryName": "Beta - OCI Storage Resources Without CMK", - "severity": "MEDIUM", - "line": 10, - "fileName": "positive2.tf" - } -] From 4d9922f68f15eaf6529bb7ef47a5fe423f195331 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:37 +0100 Subject: [PATCH 513/900] fix(tests): update test/positive1.tf to use platform_config for oci_compute_secure_boot_disabled --- .../test/positive1.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive1.tf b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive1.tf index e13edbd871a..9eb37116c89 100644 --- a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive1.tf +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive1.tf @@ -1,6 +1,6 @@ -resource "oci_core_instance" "positive1" { - availability_domain = "AD-1" - compartment_id = "ocid1.compartment..." - shape = "VM.Standard2.1" - # FALLO: Falta shape_config (Caso 1) -} \ No newline at end of file +resource "oci_core_instance" "positive1" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + # FAIL: Missing platform_config block (Case 1) +} From 3ec88ceaead6ab0282e72468f459ef03ed673b67 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:38 +0100 Subject: [PATCH 514/900] fix(tests): update test/positive3.tf to use platform_config for oci_compute_secure_boot_disabled --- .../test/positive3.tf | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive3.tf b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive3.tf index b16528bffe7..7b48c9d5018 100644 --- a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive3.tf +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/test/positive3.tf @@ -1,10 +1,11 @@ -resource "oci_core_instance" "positive3" { - availability_domain = "AD-1" - compartment_id = "ocid1.compartment..." - shape = "VM.Standard2.1" - - shape_config { - # FALLO: Configurado a false (Caso 3) - is_secure_boot_enabled = false - } -} \ No newline at end of file +resource "oci_core_instance" "positive3" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + + platform_config { + # FAIL: Set to false (Case 3) + type = "AMD_VM" + is_secure_boot_enabled = false + } +} From 05bb1f8702656811af8d16aad9befb34d5021b13 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:50 +0100 Subject: [PATCH 515/900] fix(queries): remove azure_defender_easm_enabled_manual from PR --- .../query.rego | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego deleted file mode 100644 index 15b9a92a906..00000000000 --- a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/query.rego +++ /dev/null @@ -1,19 +0,0 @@ -package Cx - -import data.generic.terraform as tf_lib - -# RULE 1: Generates a manual notice for each Resource Group found. -CxPolicy[result] { - doc := input.document[i] - rg := doc.resource.azurerm_resource_group[name] - - result := { - "documentId": doc.id, - "resourceType": "azurerm_resource_group", - "resourceName": tf_lib.get_resource_name(rg, name), - "searchKey": sprintf("azurerm_resource_group[%s]", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("Microsoft Defender EASM should be verified manually for resource group '%s'", [name]), - "keyActualValue": "EASM status cannot be verified statically via Terraform (Manual Verification Required)", - } -} From e10d766f7cde47f83166b0283fb30e89e9d4c0d0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:52 +0100 Subject: [PATCH 516/900] fix(queries): remove azure_defender_easm_enabled_manual from PR --- .../azure_defender_easm_enabled_manual/test/positive1.tf | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive1.tf diff --git a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive1.tf b/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive1.tf deleted file mode 100644 index dd2fcad1cd6..00000000000 --- a/assets/queries/terraform/azure/azure_defender_easm_enabled_manual/test/positive1.tf +++ /dev/null @@ -1,4 +0,0 @@ -resource "azurerm_resource_group" "audit_me" { - name = "rg-production-safety" - location = "East US" -} \ No newline at end of file From ac3a01f53c0a7a61def4f157bcea1e0c64880880 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:53 +0100 Subject: [PATCH 517/900] fix(queries): remove ibm_iam_policy_assigned_to_user_manual from PR --- .../query.rego | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/query.rego diff --git a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/query.rego b/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/query.rego deleted file mode 100644 index 6c640e7996c..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_policy_assigned_to_user_manual/query.rego +++ /dev/null @@ -1,15 +0,0 @@ -package Cx - -# CASO 1: Detección de políticas directas a usuario. -CxPolicy[result] { - doc := input.document[i] - policy := doc.resource.ibm_iam_user_policy[name] - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_iam_user_policy.%s", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "IAM policies should be assigned to Access Groups, not users", - "keyActualValue": "Direct user policy assignment detected. Manual review required to justify exception.", - } -} \ No newline at end of file From eb79f117017e692be4f0a5c21c51203e21619536 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:19:54 +0100 Subject: [PATCH 518/900] fix(queries): remove ibm_iam_restrict_apikey_creation_manual from PR --- .../ibm_iam_restrict_apikey_creation_manual/test/negative1.tf | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/negative1.tf diff --git a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/negative1.tf deleted file mode 100644 index 6f3d0627404..00000000000 --- a/assets/queries/terraform/ibm/ibm_iam_restrict_apikey_creation_manual/test/negative1.tf +++ /dev/null @@ -1,4 +0,0 @@ -# El cumplimiento es "negativo" cuando no hay políticas de IAM que auditar en este contexto. -resource "ibm_is_vpc" "example_vpc" { - name = "compliant-network" -} \ No newline at end of file From aed3d5fad7085912fd0893a0542557996a30a042 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:24 +0100 Subject: [PATCH 519/900] fix(metadata): align riskScore to severity for azure_app_service_application_insights_not_configured --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json index 62be0a6315f..d19bd476079 100644 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "721c26ff-776f-4d7a-b151-45447712343b", - "queryName": "Beta - App Service Application Insights Not Configured", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that Azure App Services and Function Apps are linked to Application Insights for performance monitoring and error tracking.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_web_app#app_settings", - "platform": "Terraform", - "descriptionID": "721c26ff", - "cloudProvider": "azure", - "cwe": "778", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "721c26ff-776f-4d7a-b151-45447712343b", + "queryName": "Beta - App Service Application Insights Not Configured", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that Azure App Services and Function Apps are linked to Application Insights for performance monitoring and error tracking.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_web_app#app_settings", + "platform": "Terraform", + "descriptionID": "721c26ff", + "cloudProvider": "azure", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From cb60367a61dd88953c11bb05f73e88a266966f81 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:26 +0100 Subject: [PATCH 520/900] fix(metadata): align riskScore to severity for azure_app_service_http_logs_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json index f0a8f890a31..6ca904e2497 100644 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "72eb3dd8-6892-47d1-9965-a5682de9f4e7", - "queryName": "Beta - App Service HTTP Logs Disabled", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that HTTP logs are enabled for Azure App Services. HTTP logs provide records of HTTP requests to the web app, which are crucial for security monitoring and debugging.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_web_app#http_logs", - "platform": "Terraform", - "descriptionID": "72eb3dd8", - "cloudProvider": "azure", - "cwe": "778", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "72eb3dd8-6892-47d1-9965-a5682de9f4e7", + "queryName": "Beta - App Service HTTP Logs Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that HTTP logs are enabled for Azure App Services. HTTP logs provide records of HTTP requests to the web app, which are crucial for security monitoring and debugging.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_web_app#http_logs", + "platform": "Terraform", + "descriptionID": "72eb3dd8", + "cloudProvider": "azure", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 1b75c409d5840dd521317a1838d3c0e6ae45c4cf Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:27 +0100 Subject: [PATCH 521/900] fix(metadata): align riskScore to severity for azure_backup_vault_cross_region_restore_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json index bc233c5d360..e4fbaa2c65f 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "0117fb32-4265-444d-8030-a0a034958489", - "queryName": "Beta - Backup Vault Cross Region Restore Disabled", - "severity": "MEDIUM", - "category": "Backup", - "descriptionText": "Ensures that 'Cross Region Restore' is enabled for Azure Backup Vaults. This allows backup data to be restored in a secondary region, which is critical for disaster recovery scenarios.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/data_protection_backup_vault#cross_region_restore_enabled", - "platform": "Terraform", - "descriptionID": "0117fb32", - "cloudProvider": "azure", - "cwe": "668", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "0117fb32-4265-444d-8030-a0a034958489", + "queryName": "Beta - Backup Vault Cross Region Restore Disabled", + "severity": "MEDIUM", + "category": "Backup", + "descriptionText": "Ensures that 'Cross Region Restore' is enabled for Azure Backup Vaults. This allows backup data to be restored in a secondary region, which is critical for disaster recovery scenarios.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/data_protection_backup_vault#cross_region_restore_enabled", + "platform": "Terraform", + "descriptionID": "0117fb32", + "cloudProvider": "azure", + "cwe": "668", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From c88e9027c8d28ddd8db8e9d6d7f8489babd55965 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:28 +0100 Subject: [PATCH 522/900] fix(metadata): align riskScore to severity for azure_backup_vault_infrastructure_encryption_disabled --- .../metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json index 7c56130a381..620cbfebaec 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json @@ -9,6 +9,6 @@ "descriptionID": "f7bf03d5", "cloudProvider": "azure", "cwe": "312", - "riskScore": "5.0", + "riskScore": "3.0", "experimental": "true" } \ No newline at end of file From ed2b4b8908066038bb593be54dfc10618d0a904c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:30 +0100 Subject: [PATCH 523/900] fix(metadata): align riskScore to severity for azure_bastion_host_missing --- .../azure_bastion_host_missing/metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json b/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json index a73d0e1786d..53090737c46 100644 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "a3e941c5-7708-40d1-943b-7093446ef5e6", - "queryName": "Beta - Azure Bastion Host Missing", - "severity": "MEDIUM", - "category": "Networking and Firewall", - "descriptionText": "Ensures that an Azure Bastion Host is present when Virtual Networks are defined. Azure Bastion provides secure and seamless RDP/SSH connectivity to your virtual machines directly from the Azure portal over SSL.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/bastion_host", - "platform": "Terraform", - "descriptionID": "a3e941c5", - "cloudProvider": "azure", - "cwe": "284", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "a3e941c5-7708-40d1-943b-7093446ef5e6", + "queryName": "Beta - Azure Bastion Host Missing", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that an Azure Bastion Host is present when Virtual Networks are defined. Azure Bastion provides secure and seamless RDP/SSH connectivity to your virtual machines directly from the Azure portal over SSL.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/bastion_host", + "platform": "Terraform", + "descriptionID": "a3e941c5", + "cloudProvider": "azure", + "cwe": "284", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From ab8e981b066445511c6f743d65e956dd6c98900c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:31 +0100 Subject: [PATCH 524/900] fix(metadata): align riskScore to severity for azure_elastic_san_public_access_enabled --- .../azure/azure_elastic_san_public_access_enabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json index b77bb94b391..af6f12884af 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json @@ -9,6 +9,6 @@ "cloudProvider": "azure", "cwe": "284", "descriptionID": "660863a5", - "riskScore": "9.0", + "riskScore": "6.0", "experimental": "true" } \ No newline at end of file From 73adf4c757916a0c1232899ac38be4bbd55c1d20 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:32 +0100 Subject: [PATCH 525/900] fix(metadata): align riskScore to severity for azure_iot_hub_defender_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json index 5a27576e68d..5c9ef2f2a75 100644 --- a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "13be738b-78fb-4d0f-a5ed-13e0f36fd385", - "queryName": "Beta - Azure IoT Hub Defender Disabled", - "severity": "MEDIUM", - "category": "Networking and Firewall", - "descriptionText": "Ensures that Microsoft Defender for IoT is enabled for Azure IoT Hubs. Defender for IoT provides threat detection and security posture management for IoT environments.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/iot_security_solution", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "693", - "descriptionID": "13be738b", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "13be738b-78fb-4d0f-a5ed-13e0f36fd385", + "queryName": "Beta - Azure IoT Hub Defender Disabled", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that Microsoft Defender for IoT is enabled for Azure IoT Hubs. Defender for IoT provides threat detection and security posture management for IoT environments.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/iot_security_solution", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "693", + "descriptionID": "13be738b", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 52553bf2fa2b38a34aed62852025da5489ff1a72 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:34 +0100 Subject: [PATCH 526/900] fix(metadata): align riskScore to severity for azure_key_vault_key_rotation_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json index 8828f469bcd..2303d141fc8 100644 --- a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "ca1ffce5-e2f9-4d8a-978e-719d1ed7c7fa", - "queryName": "Beta - Key Vault Key Rotation Disabled", - "severity": "MEDIUM", - "category": "Encryption", - "descriptionText": "Ensures that cryptographic keys in Azure Key Vault have an automatic rotation policy configured. Regular key rotation reduces the risk of compromised keys being used for extended periods.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key#rotation_policy", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "320", - "descriptionID": "ca1ffce5", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "ca1ffce5-e2f9-4d8a-978e-719d1ed7c7fa", + "queryName": "Beta - Key Vault Key Rotation Disabled", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that cryptographic keys in Azure Key Vault have an automatic rotation policy configured. Regular key rotation reduces the risk of compromised keys being used for extended periods.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key#rotation_policy", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "320", + "descriptionID": "ca1ffce5", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 772dd4c824762be7ff1528ce4aec533e191ec9b1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:35 +0100 Subject: [PATCH 527/900] fix(metadata): align riskScore to severity for azure_managed_lustre_cmk_encryption_disabled --- .../azure_managed_lustre_cmk_encryption_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json index 7b7b731cc78..01d30de188a 100644 --- a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json @@ -9,6 +9,6 @@ "cloudProvider": "azure", "cwe": "326", "descriptionID": "7fc653e2", - "riskScore": "5.0", + "riskScore": "3.0", "experimental": "true" } \ No newline at end of file From ad5de42428e3142e4c214814bc3940dede555ae7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:37 +0100 Subject: [PATCH 528/900] fix(metadata): align riskScore to severity for azure_paas_private_endpoint_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json index 8ee8643c2f9..38a9c981879 100644 --- a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "dda11a20-c7c2-43f8-bd52-a4c029ad15e4", - "queryName": "Beta - Ensure Private Endpoints Are Used Where Possible", - "severity": "MEDIUM", - "category": "Networking and Firewall", - "descriptionText": "Ensures that key Azure PaaS services (Cosmos DB, Storage, SQL, KeyVault, ACR, etc.) are accessed via Private Endpoints. While static analysis cannot resolve IDs across different state files, this rule validates local resource linkages.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "200", - "descriptionID": "dda11a20", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "dda11a20-c7c2-43f8-bd52-a4c029ad15e4", + "queryName": "Beta - Ensure Private Endpoints Are Used Where Possible", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that key Azure PaaS services (Cosmos DB, Storage, SQL, KeyVault, ACR, etc.) are accessed via Private Endpoints. While static analysis cannot resolve IDs across different state files, this rule validates local resource linkages.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "200", + "descriptionID": "dda11a20", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 6c672cabd600ed61c32b13665fa9ec1f3b9d75e6 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:38 +0100 Subject: [PATCH 529/900] fix(metadata): align riskScore to severity for azure_production_workload_basic_consumption_sku --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json index ecb08bcfb3e..081fe96f1a9 100644 --- a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "bd3a6fc3-fadb-472b-b06c-54c7d7645f15", - "queryName": "Beta - Production Workload using Basic or Consumption SKU", - "severity": "LOW", - "category": "Resource Management", - "descriptionText": "Detects the use of Basic, Free, or Consumption SKUs in Azure resources. These SKUs are often unsuitable for production workloads due to lack of SLAs, VNet integration support, or 'cold start' issues.", - "descriptionUrl": "https://azure.microsoft.com/en-us/pricing/details/app-service/linux/", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "1038", - "descriptionID": "bd3a6fc3", - "riskScore": "2.0", - "experimental": "true" +{ + "id": "bd3a6fc3-fadb-472b-b06c-54c7d7645f15", + "queryName": "Beta - Production Workload using Basic or Consumption SKU", + "severity": "LOW", + "category": "Resource Management", + "descriptionText": "Detects the use of Basic, Free, or Consumption SKUs in Azure resources. These SKUs are often unsuitable for production workloads due to lack of SLAs, VNet integration support, or 'cold start' issues.", + "descriptionUrl": "https://azure.microsoft.com/en-us/pricing/details/app-service/linux/", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "1038", + "descriptionID": "bd3a6fc3", + "riskScore": "1.0", + "experimental": "true" } \ No newline at end of file From d664256d4bca3c7b81e9202242b00beff75dd469 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:40 +0100 Subject: [PATCH 530/900] fix(metadata): align riskScore to severity for azure_recovery_services_vault_cross_region_restore_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json index 361210786af..f318ebd8313 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "b7b0bc16-aedc-405e-a27e-cf159c200f1e", - "queryName": "Beta - Recovery Services Vault Cross Region Restore Disabled", - "severity": "MEDIUM", - "category": "Backup", - "descriptionText": "Ensures that 'Cross Region Restore' is enabled for Azure Recovery Services Vaults. This feature allows you to restore data in the secondary region, which is essential for business continuity during a primary region disaster.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/recovery_services_vault#cross_region_restore_enabled", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "668", - "descriptionID": "b7b0bc16", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "b7b0bc16-aedc-405e-a27e-cf159c200f1e", + "queryName": "Beta - Recovery Services Vault Cross Region Restore Disabled", + "severity": "MEDIUM", + "category": "Backup", + "descriptionText": "Ensures that 'Cross Region Restore' is enabled for Azure Recovery Services Vaults. This feature allows you to restore data in the secondary region, which is essential for business continuity during a primary region disaster.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/recovery_services_vault#cross_region_restore_enabled", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "668", + "descriptionID": "b7b0bc16", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 357c1a21b471902ba83e669747495c667aa29b14 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:41 +0100 Subject: [PATCH 531/900] fix(metadata): align riskScore to severity for azure_recovery_services_vault_infrastructure_encryption_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json index 546ee1e4240..dacd0c00d53 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "95e32d9c-77b5-423a-8746-35ab59a85148", - "queryName": "Beta - Recovery Services Vault Infrastructure Encryption Disabled", - "severity": "MEDIUM", - "category": "Encryption", - "descriptionText": "Ensures that 'Infrastructure Encryption' (Double Encryption) is enabled for Azure Recovery Services Vaults. This provides a second layer of encryption for data at rest using platform-managed keys.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/recovery_services_vault#infrastructure_encryption_enabled", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "312", - "descriptionID": "95e32d9c", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "95e32d9c-77b5-423a-8746-35ab59a85148", + "queryName": "Beta - Recovery Services Vault Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that 'Infrastructure Encryption' (Double Encryption) is enabled for Azure Recovery Services Vaults. This provides a second layer of encryption for data at rest using platform-managed keys.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/recovery_services_vault#infrastructure_encryption_enabled", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "312", + "descriptionID": "95e32d9c", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 072ec5e084ff5ca8eab360f7d2d9e0c097859e31 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:42 +0100 Subject: [PATCH 532/900] fix(metadata): align riskScore to severity for azure_storage_account_geo_redundancy_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json index 597807cc04e..ca38a370736 100644 --- a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "56c748b8-9ec8-4f3e-84ac-c9a6992e1b20", - "queryName": "Beta - Storage Account Geo-Redundancy Disabled", - "severity": "MEDIUM", - "category": "Availability", - "descriptionText": "Ensures that Azure Storage Accounts use Geo-Redundant Storage (GRS, RAGRS, GZRS, or RAGZRS). This is critical for disaster recovery, ensuring data is durable even in the event of a complete regional outage.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#account_replication_type", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "668", - "descriptionID": "56c748b8", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "56c748b8-9ec8-4f3e-84ac-c9a6992e1b20", + "queryName": "Beta - Storage Account Geo-Redundancy Disabled", + "severity": "MEDIUM", + "category": "Availability", + "descriptionText": "Ensures that Azure Storage Accounts use Geo-Redundant Storage (GRS, RAGRS, GZRS, or RAGZRS). This is critical for disaster recovery, ensuring data is durable even in the event of a complete regional outage.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#account_replication_type", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "668", + "descriptionID": "56c748b8", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 73c2e97771f463eeeb5bb585e196ebf144208bfc Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:44 +0100 Subject: [PATCH 533/900] fix(metadata): align riskScore to severity for azure_storage_account_infrastructure_encryption_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json index 18f1080eea7..1e7c68de645 100644 --- a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "d02793e5-b3b5-4cfa-b379-7a81d5bfe170", - "queryName": "Beta - Storage Account Infrastructure Encryption Disabled", - "severity": "MEDIUM", - "category": "Encryption", - "descriptionText": "Ensures that 'Infrastructure Encryption' is enabled for Azure Storage Accounts. This provides a second layer of encryption (double encryption) for data at rest, protecting against the compromise of any single encryption algorithm or key.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#infrastructure_encryption_enabled", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "312", - "descriptionID": "d02793e5", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "d02793e5-b3b5-4cfa-b379-7a81d5bfe170", + "queryName": "Beta - Storage Account Infrastructure Encryption Disabled", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Ensures that 'Infrastructure Encryption' is enabled for Azure Storage Accounts. This provides a second layer of encryption (double encryption) for data at rest, protecting against the compromise of any single encryption algorithm or key.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#infrastructure_encryption_enabled", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "312", + "descriptionID": "d02793e5", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 618f322a617b4c72d80f2cbacc8484264bc7177a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:45 +0100 Subject: [PATCH 534/900] fix(metadata): align riskScore to severity for azure_storage_account_read_only_lock_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json index 14b4d2f1819..e9dcc3ecc19 100644 --- a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "3a716202-a630-4f23-b8ba-2dcbc40e2fa7", - "queryName": "Beta - Storage Account ReadOnly Lock Missing", - "severity": "LOW", - "category": "Resource Management", - "descriptionText": "Ensures that Azure Storage Accounts have a Resource Manager lock with 'ReadOnly' level applied. This prevents accidental modification or deletion of the storage account configuration.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/management_lock", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "400", - "descriptionID": "3a716202", - "riskScore": "2.0", - "experimental": "true" +{ + "id": "3a716202-a630-4f23-b8ba-2dcbc40e2fa7", + "queryName": "Beta - Storage Account ReadOnly Lock Missing", + "severity": "LOW", + "category": "Resource Management", + "descriptionText": "Ensures that Azure Storage Accounts have a Resource Manager lock with 'ReadOnly' level applied. This prevents accidental modification or deletion of the storage account configuration.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/management_lock", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "400", + "descriptionID": "3a716202", + "riskScore": "1.0", + "experimental": "true" } \ No newline at end of file From 89f277a3069579d7d92283f9fa25c43952b64e1d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:46 +0100 Subject: [PATCH 535/900] fix(metadata): align riskScore to severity for azure_storage_account_versioning_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json index 55f0443ecd3..67556653ddf 100644 --- a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "0f437572-8be4-4e05-9f76-dd266d7ad90b", - "queryName": "Beta - Storage Account Blob Versioning Disabled", - "severity": "MEDIUM", - "category": "Backup", - "descriptionText": "Ensures that 'Versioning' is enabled for Azure Storage Account Blob services. Blob versioning enables automatic retention of previous versions of an object.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#versioning_enabled", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "226", - "descriptionID": "0f437572", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "0f437572-8be4-4e05-9f76-dd266d7ad90b", + "queryName": "Beta - Storage Account Blob Versioning Disabled", + "severity": "MEDIUM", + "category": "Backup", + "descriptionText": "Ensures that 'Versioning' is enabled for Azure Storage Account Blob services. Blob versioning enables automatic retention of previous versions of an object.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#versioning_enabled", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "226", + "descriptionID": "0f437572", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 7ca809afad9480f857abb7ed2eb748f4860356df Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:47 +0100 Subject: [PATCH 536/900] fix(metadata): align riskScore to severity for azure_storage_blob_logging_disabled --- .../azure/azure_storage_blob_logging_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json index 0a4360ef5bd..7da8e4b09dc 100644 --- a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/metadata.json @@ -9,6 +9,6 @@ "cloudProvider": "azure", "cwe": "778", "descriptionID": "11fa88c0", - "riskScore": "2.0", + "riskScore": "1.0", "experimental": "true" } \ No newline at end of file From 5dfa5143fcc1850e067af9c28dcad60b2bdc29b6 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:49 +0100 Subject: [PATCH 537/900] fix(metadata): align riskScore to severity for azure_storage_container_immutability_not_locked --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json index 6b2650cc1ff..e6c03a72bd2 100644 --- a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "9b959753-3a9b-41e7-82b2-28bef91e6b53", - "queryName": "Beta - Storage Immutability Policy Not Locked", - "severity": "MEDIUM", - "category": "Access Control", - "descriptionText": "Ensures that the Immutability Policy for Azure Storage Containers is set to 'Locked'. An unlocked policy can be removed or modified, failing to provide true WORM (Write Once, Read Many) compliance for business-critical data.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_container_immutability_policy#locked", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "284", - "descriptionID": "9b959753", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "9b959753-3a9b-41e7-82b2-28bef91e6b53", + "queryName": "Beta - Storage Immutability Policy Not Locked", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that the Immutability Policy for Azure Storage Containers is set to 'Locked'. An unlocked policy can be removed or modified, failing to provide true WORM (Write Once, Read Many) compliance for business-critical data.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_container_immutability_policy#locked", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "284", + "descriptionID": "9b959753", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 2ceb5cfb1e568662f86f0c76aced8ce101967723 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:50 +0100 Subject: [PATCH 538/900] fix(metadata): align riskScore to severity for azure_storage_queue_logging_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json index 3c3ff8609d9..e2c700e33a7 100644 --- a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "cddbdd74-3736-4aec-ba57-43b4db315bc2", - "queryName": "Beta - Storage Queue Service Logging Disabled", - "severity": "LOW", - "category": "Observability", - "descriptionText": "Ensures that Storage Logging is enabled for the Queue service for 'Read', 'Write', and 'Delete' requests. This provides an audit trail of operations performed on the queues.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#logging", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "778", - "descriptionID": "cddbdd74", - "riskScore": "2.0", - "experimental": "true" +{ + "id": "cddbdd74-3736-4aec-ba57-43b4db315bc2", + "queryName": "Beta - Storage Queue Service Logging Disabled", + "severity": "LOW", + "category": "Observability", + "descriptionText": "Ensures that Storage Logging is enabled for the Queue service for 'Read', 'Write', and 'Delete' requests. This provides an audit trail of operations performed on the queues.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#logging", + "platform": "Terraform", + "cloudProvider": "azure", + "cwe": "778", + "descriptionID": "cddbdd74", + "riskScore": "1.0", + "experimental": "true" } \ No newline at end of file From edcebc699ad903901b58b913a7abccd77c28ca4a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:51 +0100 Subject: [PATCH 539/900] fix(metadata): align riskScore to severity for azure_storage_table_logging_disabled --- .../azure/azure_storage_table_logging_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json index c7ced4d9035..92ff060f6f4 100644 --- a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/metadata.json @@ -9,6 +9,6 @@ "cloudProvider": "azure", "cwe": "778", "descriptionID": "0d29e3cf", - "riskScore": "2.0", + "riskScore": "1.0", "experimental": "true" } \ No newline at end of file From 5e55e6c176ea48e83d2dee60d37b0688016d5084 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:52 +0100 Subject: [PATCH 540/900] fix(metadata): align riskScore to severity for gcp_access_approval_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json index 79455656962..367dac43efa 100644 --- a/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "d7df9989-f87a-45cb-80ea-d4d20e3d4530", - "queryName": "Beta - GCP Access Approval Disabled", - "severity": "MEDIUM", - "category": "Access Control", - "descriptionText": "Ensures that Access Approval is enabled for the GCP Project. Access Approval allows you to approve or deny access to your data by Google support and engineering personnel.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/access_approval_project_settings", - "platform": "Terraform", - "descriptionID": "d7df9989", - "cloudProvider": "gcp", - "cwe": "284", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "d7df9989-f87a-45cb-80ea-d4d20e3d4530", + "queryName": "Beta - GCP Access Approval Disabled", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that Access Approval is enabled for the GCP Project. Access Approval allows you to approve or deny access to your data by Google support and engineering personnel.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/access_approval_project_settings", + "platform": "Terraform", + "descriptionID": "d7df9989", + "cloudProvider": "gcp", + "cwe": "284", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From b900d6b88a1704128ba4f186beb1519f4b1467e7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:54 +0100 Subject: [PATCH 541/900] fix(metadata): align riskScore to severity for gcp_api_key_api_targets_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json index 76c5e2bb585..5546305fb78 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "8097afd6-ef1a-4a58-b5f8-5d1b70ab4818", - "queryName": "Beta - Google API Key API Targets Missing", - "severity": "MEDIUM", - "category": "Access Control", - "descriptionText": "Ensures that Google Cloud API Keys are restricted to specific APIs. By default, an API key can be used to access any API enabled in the project, which increases the blast radius if the key is compromised.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/apikeys_key#api_targets", - "platform": "Terraform", - "descriptionID": "8097afd6", - "cloudProvider": "gcp", - "cwe": "284", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "8097afd6-ef1a-4a58-b5f8-5d1b70ab4818", + "queryName": "Beta - Google API Key API Targets Missing", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that Google Cloud API Keys are restricted to specific APIs. By default, an API key can be used to access any API enabled in the project, which increases the blast radius if the key is compromised.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/apikeys_key#api_targets", + "platform": "Terraform", + "descriptionID": "8097afd6", + "cloudProvider": "gcp", + "cwe": "284", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From cdd0bcfa02da3a01e5608f8e88119d391b14fc12 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:56 +0100 Subject: [PATCH 542/900] fix(metadata): align riskScore to severity for gcp_compute_logging_service_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json index 4c5ac85ff83..0fb133488c5 100644 --- a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "ccefc589-0310-45a4-a2b6-d558e629e019", - "queryName": "Beta - GCP Compute Logging Service Disabled", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that the 'google-logging-enabled' metadata flag is set to 'true' for Google Compute Engine instances. This flag configures the instance to send logs to Cloud Logging.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#metadata", - "platform": "Terraform", - "descriptionID": "ccefc589", - "cloudProvider": "gcp", - "cwe": "778", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "ccefc589-0310-45a4-a2b6-d558e629e019", + "queryName": "Beta - GCP Compute Logging Service Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that the 'google-logging-enabled' metadata flag is set to 'true' for Google Compute Engine instances. This flag configures the instance to send logs to Cloud Logging.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#metadata", + "platform": "Terraform", + "descriptionID": "ccefc589", + "cloudProvider": "gcp", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From a0aba438063d9d380442af32ebb7ff17c2ea7690 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:57 +0100 Subject: [PATCH 543/900] fix(metadata): align riskScore to severity for gcp_gke_default_service_account_used --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json index b46ce5d7602..98af937f545 100644 --- a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "8ef3f681-6ef1-4bbd-94bb-f9fe6d0626da", - "queryName": "Beta - GKE Default Service Account Used", - "severity": "HIGH", - "category": "Access Control", - "descriptionText": "Ensures that GKE clusters do not use the default Compute Engine Service Account. The default account has the 'Editor' role, granting nodes excessive write permissions to the project.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_cluster#service_account", - "platform": "Terraform", - "descriptionID": "8ef3f681", - "cloudProvider": "gcp", - "cwe": "276", - "riskScore": "9.0", - "experimental": "true" +{ + "id": "8ef3f681-6ef1-4bbd-94bb-f9fe6d0626da", + "queryName": "Beta - GKE Default Service Account Used", + "severity": "HIGH", + "category": "Access Control", + "descriptionText": "Ensures that GKE clusters do not use the default Compute Engine Service Account. The default account has the 'Editor' role, granting nodes excessive write permissions to the project.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_cluster#service_account", + "platform": "Terraform", + "descriptionID": "8ef3f681", + "cloudProvider": "gcp", + "cwe": "276", + "riskScore": "6.0", + "experimental": "true" } \ No newline at end of file From 2b014139fd0b7f65ae1d26934e2c867569e782d0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:22:59 +0100 Subject: [PATCH 544/900] fix(metadata): align riskScore to severity for gcp_gke_metadata_server_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json index 3e41f143bd7..7969806019e 100644 --- a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "e858428b-7650-4a62-a7d4-5b0d4c9afdd6", - "queryName": "Beta - GKE Metadata Server Disabled", - "severity": "HIGH", - "category": "Access Control", - "descriptionText": "Ensures that the GKE Metadata Server is enabled by setting 'workload_metadata_config.mode' to 'GKE_METADATA'. This prevents pods from accessing the sensitive Compute Engine metadata server and node credentials.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_node_pool#mode", - "platform": "Terraform", - "descriptionID": "e858428b", - "cloudProvider": "gcp", - "cwe": "284", - "riskScore": "9.0", - "experimental": "true" +{ + "id": "e858428b-7650-4a62-a7d4-5b0d4c9afdd6", + "queryName": "Beta - GKE Metadata Server Disabled", + "severity": "HIGH", + "category": "Access Control", + "descriptionText": "Ensures that the GKE Metadata Server is enabled by setting 'workload_metadata_config.mode' to 'GKE_METADATA'. This prevents pods from accessing the sensitive Compute Engine metadata server and node credentials.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_node_pool#mode", + "platform": "Terraform", + "descriptionID": "e858428b", + "cloudProvider": "gcp", + "cwe": "284", + "riskScore": "6.0", + "experimental": "true" } \ No newline at end of file From 27c88e7db07b11f303a01e2dd085ed578c8fdce6 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:00 +0100 Subject: [PATCH 545/900] fix(metadata): align riskScore to severity for gcp_gke_sandbox_disabled --- .../gcp_gke_sandbox_disabled/metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json index a66fdd88ddc..bca92c1a9ea 100644 --- a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "6c8a93a9-c0c5-4314-8ee6-3bcb3a0dbd70", - "queryName": "Beta - GKE Sandbox (gVisor) Disabled", - "severity": "LOW", - "category": "Insecure Configurations", - "descriptionText": "GKE Sandbox (gVisor) provides an extra layer of defense for untrusted workloads. It is not enabled on this Node Pool. Consider enabling it if this pool runs untrusted code (e.g., SaaS user scripts).", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_node_pool#sandbox_type", - "platform": "Terraform", - "descriptionID": "6c8a93a9", - "cloudProvider": "gcp", - "cwe": "1038", - "riskScore": "3.0", - "experimental": "true" +{ + "id": "6c8a93a9-c0c5-4314-8ee6-3bcb3a0dbd70", + "queryName": "Beta - GKE Sandbox (gVisor) Disabled", + "severity": "LOW", + "category": "Insecure Configurations", + "descriptionText": "GKE Sandbox (gVisor) provides an extra layer of defense for untrusted workloads. It is not enabled on this Node Pool. Consider enabling it if this pool runs untrusted code (e.g., SaaS user scripts).", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_node_pool#sandbox_type", + "platform": "Terraform", + "descriptionID": "6c8a93a9", + "cloudProvider": "gcp", + "cwe": "1038", + "riskScore": "1.0", + "experimental": "true" } \ No newline at end of file From d25783d300734a30838b5055ac404df4ae6ed491 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:01 +0100 Subject: [PATCH 546/900] fix(metadata): align riskScore to severity for gcp_gke_secrets_encryption_cmek_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json index ca14d3aecfe..975d2c9ecbb 100644 --- a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "83d1c89f-e07c-4748-9d96-51a78c49637c", - "queryName": "Beta - GKE Secrets Not Encrypted with CMEK", - "severity": "HIGH", - "category": "Encryption", - "descriptionText": "Ensures that GKE clusters have Application-Layer Secrets Encryption enabled using a Cloud KMS key. This protects sensitive data in etcd with a customer-managed encryption key.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_cluster#database_encryption", - "platform": "Terraform", - "descriptionID": "83d1c89f", - "cloudProvider": "gcp", - "cwe": "312", - "riskScore": "9.0", - "experimental": "true" +{ + "id": "83d1c89f-e07c-4748-9d96-51a78c49637c", + "queryName": "Beta - GKE Secrets Not Encrypted with CMEK", + "severity": "HIGH", + "category": "Encryption", + "descriptionText": "Ensures that GKE clusters have Application-Layer Secrets Encryption enabled using a Cloud KMS key. This protects sensitive data in etcd with a customer-managed encryption key.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_cluster#database_encryption", + "platform": "Terraform", + "descriptionID": "83d1c89f", + "cloudProvider": "gcp", + "cwe": "312", + "riskScore": "6.0", + "experimental": "true" } \ No newline at end of file From 8909800e863d956a9040e07ef3c35a0f7dec7b5d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:03 +0100 Subject: [PATCH 547/900] fix(metadata): align riskScore to severity for gcp_http_load_balancer_logging_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json index 407d3fa2d4c..129d02817c7 100644 --- a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "0ef3f3f1-0592-475b-b073-81ac1ac869e2", - "queryName": "Beta - GCP HTTP(S) Load Balancer Logging Disabled", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that logging is enabled for Google Compute Backend Services used in HTTP(S) Load Balancers. Access logs are essential for monitoring traffic patterns, latency, and identifying potential security threats.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_backend_service#log_config", - "platform": "Terraform", - "descriptionID": "0ef3f3f1", - "cloudProvider": "gcp", - "cwe": "778", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "0ef3f3f1-0592-475b-b073-81ac1ac869e2", + "queryName": "Beta - GCP HTTP(S) Load Balancer Logging Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that logging is enabled for Google Compute Backend Services used in HTTP(S) Load Balancers. Access logs are essential for monitoring traffic patterns, latency, and identifying potential security threats.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_backend_service#log_config", + "platform": "Terraform", + "descriptionID": "0ef3f3f1", + "cloudProvider": "gcp", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From bed807ca9558b8ba26a23890b06d5bfd5bfb4462 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:05 +0100 Subject: [PATCH 548/900] fix(metadata): align riskScore to severity for gcp_iap_backend_service_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json index 694b775059c..1b2b541a26c 100644 --- a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "3f1222a9-0161-4fe8-b188-ccabaf7a0ba5", - "queryName": "Beta - IAP Disabled on Backend Service", - "severity": "MEDIUM", - "category": "Access Control", - "descriptionText": "Ensures that Identity-Aware Proxy (IAP) is enabled for Google Compute Backend Services. IAP verifies user identity and context before allowing access to applications.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_backend_service#iap", - "platform": "Terraform", - "descriptionID": "3f1222a9", - "cloudProvider": "gcp", - "cwe": "284", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "3f1222a9-0161-4fe8-b188-ccabaf7a0ba5", + "queryName": "Beta - IAP Disabled on Backend Service", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that Identity-Aware Proxy (IAP) is enabled for Google Compute Backend Services. IAP verifies user identity and context before allowing access to applications.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_backend_service#iap", + "platform": "Terraform", + "descriptionID": "3f1222a9", + "cloudProvider": "gcp", + "cwe": "284", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From d94014eaba60c915c0a55f128e1e9c21d4158483 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:06 +0100 Subject: [PATCH 549/900] fix(metadata): align riskScore to severity for gcp_sql_postgresql_log_error_verbosity_verbose --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json index fcc80188a28..ca06ed59e94 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "80d98d7b-2f12-4a8c-8cc9-fd17ca19c569", - "queryName": "Beta - Cloud SQL PostgreSQL log_error_verbosity is Verbose", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that the 'log_error_verbosity' flag for Cloud SQL PostgreSQL instances is set to 'default' or 'terse'. Setting it to 'verbose' generates excessive logs containing internal source code details, which can be a security risk.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance", - "platform": "Terraform", - "descriptionID": "80d98d7b", - "cloudProvider": "gcp", - "cwe": "532", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "80d98d7b-2f12-4a8c-8cc9-fd17ca19c569", + "queryName": "Beta - Cloud SQL PostgreSQL log_error_verbosity is Verbose", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that the 'log_error_verbosity' flag for Cloud SQL PostgreSQL instances is set to 'default' or 'terse'. Setting it to 'verbose' generates excessive logs containing internal source code details, which can be a security risk.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance", + "platform": "Terraform", + "descriptionID": "80d98d7b", + "cloudProvider": "gcp", + "cwe": "532", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 6ec0ba0656abe856e3ecc02ca3f48ef9f348aae8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:08 +0100 Subject: [PATCH 550/900] fix(metadata): align riskScore to severity for gcp_sql_postgresql_log_statement_improperly_set --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json index 892d75807d9..e9fc93024a9 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "ede2d9e4-d3a6-4751-a89b-561bc9bacbe4", - "queryName": "Beta - Cloud SQL PostgreSQL log_statement Improperly Set", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that the 'log_statement' database flag for Cloud SQL PostgreSQL instances is set to 'ddl', 'mod', or 'all'. The default value is 'none', which disables statement logging and hinders auditing capability.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance", - "platform": "Terraform", - "descriptionID": "ede2d9e4", - "cloudProvider": "gcp", - "cwe": "778", - "riskScore": "5.0", - "experimental": "true" +{ + "id": "ede2d9e4-d3a6-4751-a89b-561bc9bacbe4", + "queryName": "Beta - Cloud SQL PostgreSQL log_statement Improperly Set", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that the 'log_statement' database flag for Cloud SQL PostgreSQL instances is set to 'ddl', 'mod', or 'all'. The default value is 'none', which disables statement logging and hinders auditing capability.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance", + "platform": "Terraform", + "descriptionID": "ede2d9e4", + "cloudProvider": "gcp", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From be921c4a3139182c3066b3bac61261854a621979 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:09 +0100 Subject: [PATCH 551/900] fix(metadata): align riskScore to severity for ibm_activity_tracker_global_events_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json index b33534c72ab..70c4e2a8bb7 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "479bbdfd-342a-4121-8844-7387eea26d96", - "queryName": "Beta - Activity Tracker for Global Events Disabled", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that an IBM Cloud Activity Tracker instance is provisioned to capture IAM and other global account events. For compliance and security, at least one instance must be configured in a region that supports receiving global events.", - "descriptionUrl": "https://cloud.ibm.com/docs/activity-tracker?topic=activity-tracker-global-events", - "platform": "Terraform", - "descriptionID": "479bbdfd", - "cloudProvider": "ibm", - "cwe": "778", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "479bbdfd-342a-4121-8844-7387eea26d96", + "queryName": "Beta - Activity Tracker for Global Events Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that an IBM Cloud Activity Tracker instance is provisioned to capture IAM and other global account events. For compliance and security, at least one instance must be configured in a region that supports receiving global events.", + "descriptionUrl": "https://cloud.ibm.com/docs/activity-tracker?topic=activity-tracker-global-events", + "platform": "Terraform", + "descriptionID": "479bbdfd", + "cloudProvider": "ibm", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From a4afe27f0a3222e9b4abebde80aa873b00a1fd71 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:10 +0100 Subject: [PATCH 552/900] fix(metadata): align riskScore to severity for ibm_activity_tracker_platform_logs_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json index 89b5f98b13a..bb5f26ee9c8 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "ccf65fe5-85f2-414d-b68e-b5101bc4bc03", - "queryName": "Beta - Activity Tracker Platform Logs Disabled", - "severity": "HIGH", - "category": "Observability", - "descriptionText": "Ensures that the IBM Cloud Activity Tracker instance is configured to receive platform logs. Capturing platform management events is critical for security auditing, threat detection, and compliance.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_instance#platform_logs", - "platform": "Terraform", - "descriptionID": "ccf65fe5", - "cloudProvider": "ibm", - "cwe": "778", - "riskScore": 6.0, - "experimental": "true" +{ + "id": "ccf65fe5-85f2-414d-b68e-b5101bc4bc03", + "queryName": "Beta - Activity Tracker Platform Logs Disabled", + "severity": "HIGH", + "category": "Observability", + "descriptionText": "Ensures that the IBM Cloud Activity Tracker instance is configured to receive platform logs. Capturing platform management events is critical for security auditing, threat detection, and compliance.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_instance#platform_logs", + "platform": "Terraform", + "descriptionID": "ccf65fe5", + "cloudProvider": "ibm", + "cwe": "778", + "riskScore": "6.0", + "experimental": "true" } \ No newline at end of file From 9376fcc83ae80251967fd7d80b74cec915eae1c0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:11 +0100 Subject: [PATCH 553/900] fix(metadata): align riskScore to severity for ibm_certificate_manager_auto_renew_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json index 67547ffe99d..2faa7ff758a 100644 --- a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "6797782b-0523-4419-9297-1747e1bf82ab", - "queryName": "Beta - Certificate Manager Auto Renew Disabled", - "severity": "MEDIUM", - "category": "Best Practices", - "descriptionText": "Ensures that certificates managed by IBM Cloud Certificate Manager are configured to renew automatically before expiration. Disabling auto-renewal can lead to service disruptions and security risks due to expired certificates.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/cm_certificate#auto_renew_enabled", - "platform": "Terraform", - "descriptionID": "6797782b", - "cloudProvider": "ibm", - "cwe": "320", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "6797782b-0523-4419-9297-1747e1bf82ab", + "queryName": "Beta - Certificate Manager Auto Renew Disabled", + "severity": "MEDIUM", + "category": "Best Practices", + "descriptionText": "Ensures that certificates managed by IBM Cloud Certificate Manager are configured to renew automatically before expiration. Disabling auto-renewal can lead to service disruptions and security risks due to expired certificates.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/cm_certificate#auto_renew_enabled", + "platform": "Terraform", + "descriptionID": "6797782b", + "cloudProvider": "ibm", + "cwe": "320", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 1ed891c82fef3487bd09011ce965483801e00805 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:15 +0100 Subject: [PATCH 554/900] fix(metadata): align riskScore to severity for ibm_container_registry_va_alerts_missing --- .../ibm/ibm_container_registry_va_alerts_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json index bbbaca424ec..8606b13d73c 100644 --- a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json +++ b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/metadata.json @@ -9,6 +9,6 @@ "descriptionID": "92440d0d", "cloudProvider": "ibm", "cwe": "778", - "riskScore": 3.0, + "riskScore": "3.0", "experimental": "true" } \ No newline at end of file From 882d198db88e8f28680b5fb0046cba405ba7bd20 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:17 +0100 Subject: [PATCH 555/900] fix(metadata): align riskScore to severity for ibm_iam_account_mfa_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json index b5ba4cd7d10..0c198b17ae8 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "ebaef99e-4add-440e-8270-caeb718e7c93", - "queryName": "Beta - Account Level MFA Is Not Enforced", - "severity": "HIGH", - "category": "Access Control", - "descriptionText": "Enforces Multi-Factor Authentication (MFA) at the account level. Requiring MFA is a fundamental security practice to prevent unauthorized access resulting from compromised credentials.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_account_settings#mfa", - "platform": "Terraform", - "descriptionID": "ebaef99e", - "cloudProvider": "ibm", - "cwe": "308", - "riskScore": 9.0, - "experimental": "true" +{ + "id": "ebaef99e-4add-440e-8270-caeb718e7c93", + "queryName": "Beta - Account Level MFA Is Not Enforced", + "severity": "HIGH", + "category": "Access Control", + "descriptionText": "Enforces Multi-Factor Authentication (MFA) at the account level. Requiring MFA is a fundamental security practice to prevent unauthorized access resulting from compromised credentials.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_account_settings#mfa", + "platform": "Terraform", + "descriptionID": "ebaef99e", + "cloudProvider": "ibm", + "cwe": "308", + "riskScore": "6.0", + "experimental": "true" } \ No newline at end of file From 14e802b71b5fb499852c415c2e3c85cf817f63c1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:18 +0100 Subject: [PATCH 556/900] fix(metadata): align riskScore to severity for ibm_iam_session_expiration_too_long --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json index 7f668e1132c..225cfb71711 100644 --- a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "3d6db2d6-fa2d-41df-a783-d3dee76f717f", - "queryName": "Beta - IBM Account Session Expiration Too Long", - "severity": "MEDIUM", - "category": "Access Control", - "descriptionText": "Ensures that the IBM Cloud account session expiration is configured to a secure limit (e.g., 3600 seconds / 1 hour). Long session timeouts increase the risk of session hijacking.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_account_settings", - "platform": "Terraform", - "descriptionID": "3d6db2d6", - "cloudProvider": "ibm", - "cwe": "613", - "riskScore": 5.0, - "experimental": "true" +{ + "id": "3d6db2d6-fa2d-41df-a783-d3dee76f717f", + "queryName": "Beta - IBM Account Session Expiration Too Long", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that the IBM Cloud account session expiration is configured to a secure limit (e.g., 3600 seconds / 1 hour). Long session timeouts increase the risk of session hijacking.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_account_settings", + "platform": "Terraform", + "descriptionID": "3d6db2d6", + "cloudProvider": "ibm", + "cwe": "613", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 00f98378d4c5aaaa67d3ce8927d47a7bfa365081 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:20 +0100 Subject: [PATCH 557/900] fix(metadata): align riskScore to severity for ibm_iks_cluster_logging_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json index 11e1c58e2da..2c21269ef43 100644 --- a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "e55a0224-47b8-41a8-8cc1-8c8581e13a8d", - "queryName": "Beta - IKS Cluster Logging Disabled", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that every IBM Cloud Kubernetes Service (IKS) cluster has an associated logging service configuration. Centralized logging is essential for troubleshooting applications, monitoring cluster activity, and performing security analysis.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/ob_logging_config", - "platform": "Terraform", - "descriptionID": "e55a0224", - "cloudProvider": "ibm", - "cwe": "778", - "riskScore": 5.0, - "experimental": "true" +{ + "id": "e55a0224-47b8-41a8-8cc1-8c8581e13a8d", + "queryName": "Beta - IKS Cluster Logging Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that every IBM Cloud Kubernetes Service (IKS) cluster has an associated logging service configuration. Centralized logging is essential for troubleshooting applications, monitoring cluster activity, and performing security analysis.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/ob_logging_config", + "platform": "Terraform", + "descriptionID": "e55a0224", + "cloudProvider": "ibm", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 4f2e7e5e5f647efe402f9e8d891cbe5831af7bf8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:21 +0100 Subject: [PATCH 558/900] fix(metadata): align riskScore to severity for ibm_iks_cluster_monitoring_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json index f3ca90151be..2393102c4a2 100644 --- a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "51bac252-399d-49d0-bfa5-0bd52194fed9", - "queryName": "Beta - IKS Cluster Monitoring Disabled", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that every IBM Cloud Kubernetes Service (IKS) cluster has an associated monitoring service configuration. Monitoring is essential for observing cluster health, performance, and resource utilization.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/ob_monitoring_config", - "platform": "Terraform", - "descriptionID": "51bac252", - "cloudProvider": "ibm", - "cwe": "778", - "riskScore": 5.0, - "experimental": "true" +{ + "id": "51bac252-399d-49d0-bfa5-0bd52194fed9", + "queryName": "Beta - IKS Cluster Monitoring Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that every IBM Cloud Kubernetes Service (IKS) cluster has an associated monitoring service configuration. Monitoring is essential for observing cluster health, performance, and resource utilization.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/ob_monitoring_config", + "platform": "Terraform", + "descriptionID": "51bac252", + "cloudProvider": "ibm", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 070b43fb1b276aaf13b2b5fb8685ca2cd8d6e077 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:23 +0100 Subject: [PATCH 559/900] fix(metadata): align riskScore to severity for ibm_kms_key_rotation_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json index 74ed670cbf1..f6aa17272b3 100644 --- a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "cdaf415c-d1b9-4d15-8e6f-e27165b49d55", - "queryName": "Beta - KMS Key Rotation Disabled", - "severity": "HIGH", - "category": "Encryption", - "descriptionText": "Ensures that cryptographic keys in IBM Key Protect have an automated rotation policy enabled. Rotating keys periodically limits the amount of data exposed if a single key is compromised.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/kms_key#rotation_policy", - "platform": "Terraform", - "descriptionID": "cdaf415c", - "cloudProvider": "ibm", - "cwe": "320", - "riskScore": 9.0, - "experimental": "true" +{ + "id": "cdaf415c-d1b9-4d15-8e6f-e27165b49d55", + "queryName": "Beta - KMS Key Rotation Disabled", + "severity": "HIGH", + "category": "Encryption", + "descriptionText": "Ensures that cryptographic keys in IBM Key Protect have an automated rotation policy enabled. Rotating keys periodically limits the amount of data exposed if a single key is compromised.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/kms_key#rotation_policy", + "platform": "Terraform", + "descriptionID": "cdaf415c", + "cloudProvider": "ibm", + "cwe": "320", + "riskScore": "6.0", + "experimental": "true" } \ No newline at end of file From 1027a7cc567d4e264ae7771d2f89546ee539a5f5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:24 +0100 Subject: [PATCH 560/900] fix(metadata): align riskScore to severity for ibm_logdna_archiving_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json index 62b7804a9af..32db0a7adcf 100644 --- a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json +++ b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "54c5b041-1902-4e19-b414-5473f1b349d2", - "queryName": "Beta - LogDNA Archiving Is Disabled", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that every IBM LogDNA instance has archiving configured through an 'ibm_logdna_archive' resource. Archiving is critical for long-term log retention, compliance, and forensic analysis.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/logdna_archive", - "platform": "Terraform", - "descriptionID": "54c5b041", - "cloudProvider": "ibm", - "cwe": "223", - "riskScore": 5.0, - "experimental": "true" +{ + "id": "54c5b041-1902-4e19-b414-5473f1b349d2", + "queryName": "Beta - LogDNA Archiving Is Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that every IBM LogDNA instance has archiving configured through an 'ibm_logdna_archive' resource. Archiving is critical for long-term log retention, compliance, and forensic analysis.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/logdna_archive", + "platform": "Terraform", + "descriptionID": "54c5b041", + "cloudProvider": "ibm", + "cwe": "223", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 35c29da5e9c77adf6dabfc929b0aa3a9d1bed772 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:26 +0100 Subject: [PATCH 561/900] fix(metadata): align riskScore to severity for ibm_logdna_view_without_alert --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json index e3aba5ae6b7..fc0f70b59ef 100644 --- a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json +++ b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "a5107e68-028f-4b4d-9fc0-f23e3b73e448", - "queryName": "Beta - LogDNA View Without Alert", - "severity": "LOW", - "category": "Observability", - "descriptionText": "Ensures that every IBM LogDNA custom view ('ibm_logdna_view') has at least one associated alert ('ibm_logdna_alert'). Views are created to filter critical events, and without an alert, notifications for these events will not be sent.", - "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/logdna_alert", - "platform": "Terraform", - "descriptionID": "a5107e68", - "cloudProvider": "ibm", - "cwe": "778", - "riskScore": 1.0, - "experimental": "true" +{ + "id": "a5107e68-028f-4b4d-9fc0-f23e3b73e448", + "queryName": "Beta - LogDNA View Without Alert", + "severity": "LOW", + "category": "Observability", + "descriptionText": "Ensures that every IBM LogDNA custom view ('ibm_logdna_view') has at least one associated alert ('ibm_logdna_alert'). Views are created to filter critical events, and without an alert, notifications for these events will not be sent.", + "descriptionUrl": "https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/logdna_alert", + "platform": "Terraform", + "descriptionID": "a5107e68", + "cloudProvider": "ibm", + "cwe": "778", + "riskScore": "1.0", + "experimental": "true" } \ No newline at end of file From 16a5d59cc8dda92d817320aba2d16785bd8a0e99 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:27 +0100 Subject: [PATCH 562/900] fix(metadata): align riskScore to severity for oci_cloud_guard_problem_event_rule_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json index cadf393c214..812b743e7cb 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "3ce366ab-e97d-4040-aa67-5a08dad595fb", - "queryName": "Beta - Event Rule for Cloud Guard Problems is Missing", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that an OCI event rule is configured to create notifications for problems detected by Cloud Guard. Without a notification rule, critical security findings from Cloud Guard may go unnoticed, delaying response to potential threats.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", - "platform": "Terraform", - "descriptionID": "3ce366ab", - "cloudProvider": "oci", - "cwe": "778", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "3ce366ab-e97d-4040-aa67-5a08dad595fb", + "queryName": "Beta - Event Rule for Cloud Guard Problems is Missing", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that an OCI event rule is configured to create notifications for problems detected by Cloud Guard. Without a notification rule, critical security findings from Cloud Guard may go unnoticed, delaying response to potential threats.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "3ce366ab", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From b5c0fd7ab8613b143dd6bfbe23e6352e5317577d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:28 +0100 Subject: [PATCH 563/900] fix(metadata): align riskScore to severity for oci_cloud_guard_root_compartment_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json index 70dad5bcde8..82785af85db 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "3e784705-b3c6-4197-9a04-0b751b1a83d8", - "queryName": "Beta - Cloud Guard Not Enabled at Root Compartment", - "severity": "HIGH", - "category": "Security Services", - "descriptionText": "Ensures that OCI Cloud Guard is enabled at the tenancy's root compartment. Cloud Guard is a cloud-native security posture management service that helps monitor, identify, and maintain a strong security posture on Oracle Cloud.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/cloud_guard_configuration", - "platform": "Terraform", - "descriptionID": "3e784705", - "cloudProvider": "oci", - "cwe": "16", - "riskScore": 6.0, - "experimental": "true" +{ + "id": "3e784705-b3c6-4197-9a04-0b751b1a83d8", + "queryName": "Beta - Cloud Guard Not Enabled at Root Compartment", + "severity": "HIGH", + "category": "Security Services", + "descriptionText": "Ensures that OCI Cloud Guard is enabled at the tenancy's root compartment. Cloud Guard is a cloud-native security posture management service that helps monitor, identify, and maintain a strong security posture on Oracle Cloud.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/cloud_guard_configuration", + "platform": "Terraform", + "descriptionID": "3e784705", + "cloudProvider": "oci", + "cwe": "16", + "riskScore": "6.0", + "experimental": "true" } \ No newline at end of file From 3eb3a875810b47238fbed146dd2956be0c192147 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:30 +0100 Subject: [PATCH 564/900] fix(metadata): align riskScore to severity for oci_compute_legacy_metadata_enabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json index 8abe6f94857..727a7f2537a 100644 --- a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "96b464dc-a778-4b99-8634-c9eb9bdecf89", - "queryName": "Beta - Compute Instance Legacy Metadata Enabled", - "severity": "MEDIUM", - "category": "Insecure Configurations", - "descriptionText": "Ensures that OCI Compute Instances have legacy metadata service endpoints (IMDSv1) disabled. Enforcing the use of IMDSv2 is a security best practice to mitigate Server-Side Request Forgery (SSRF) vulnerabilities.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_instance#are_legacy_imds_endpoints_disabled", - "platform": "Terraform", - "descriptionID": "96b464dc", - "cloudProvider": "oci", - "cwe": "918", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "96b464dc-a778-4b99-8634-c9eb9bdecf89", + "queryName": "Beta - Compute Instance Legacy Metadata Enabled", + "severity": "MEDIUM", + "category": "Insecure Configurations", + "descriptionText": "Ensures that OCI Compute Instances have legacy metadata service endpoints (IMDSv1) disabled. Enforcing the use of IMDSv2 is a security best practice to mitigate Server-Side Request Forgery (SSRF) vulnerabilities.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_instance#are_legacy_imds_endpoints_disabled", + "platform": "Terraform", + "descriptionID": "96b464dc", + "cloudProvider": "oci", + "cwe": "918", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 7c77d9eb08b0b31cb77a5afe37804fd2f4d9fee7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:31 +0100 Subject: [PATCH 565/900] fix(metadata): align riskScore to severity for oci_compute_secure_boot_disabled --- .../oci/oci_compute_secure_boot_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json index f44266025ee..88b5c0a344e 100644 --- a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/metadata.json @@ -9,6 +9,6 @@ "descriptionID": "1f24d72d", "cloudProvider": "oci", "cwe": "427", - "riskScore": 3.0, + "riskScore": "3.0", "experimental": "true" } \ No newline at end of file From 284e83953ae360283d689820bb3585925b017492 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:32 +0100 Subject: [PATCH 566/900] fix(metadata): align riskScore to severity for oci_default_tags_not_defined --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json b/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json index 9848e4526b9..31b147c9007 100644 --- a/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json +++ b/assets/queries/terraform/oci/oci_default_tags_not_defined/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "4c294256-f477-41d5-8c7f-f31c9e48092e", - "queryName": "Beta - Default Tags Not Defined", - "severity": "LOW", - "category": "Best Practices", - "descriptionText": "Ensures that a default tagging policy is defined using the 'oci_identity_tag_default' resource. Default tags are crucial for governance as they ensure all resources within a compartment are automatically tagged for cost tracking, automation, and access control.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/identity_tag_default", - "platform": "Terraform", - "descriptionID": "4c294256", - "cloudProvider": "oci", - "cwe": "16", - "riskScore": 1.0, - "experimental": "true" +{ + "id": "4c294256-f477-41d5-8c7f-f31c9e48092e", + "queryName": "Beta - Default Tags Not Defined", + "severity": "LOW", + "category": "Best Practices", + "descriptionText": "Ensures that a default tagging policy is defined using the 'oci_identity_tag_default' resource. Default tags are crucial for governance as they ensure all resources within a compartment are automatically tagged for cost tracking, automation, and access control.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/identity_tag_default", + "platform": "Terraform", + "descriptionID": "4c294256", + "cloudProvider": "oci", + "cwe": "16", + "riskScore": "1.0", + "experimental": "true" } \ No newline at end of file From e84ad705a8ebce72dbc1c5fee56685764c79bd6b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:33 +0100 Subject: [PATCH 567/900] fix(metadata): align riskScore to severity for oci_iam_group_change_event_rule_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json index f538a2942f5..8d265583e53 100644 --- a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "3f6ba6dd-fa6d-45b4-8b27-120b7ebb4d0f", - "queryName": "Beta - Event Rule for IAM Group Changes is Missing", - "severity": "MEDIUM", - "category": "Access Control", - "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to IAM groups. Auditing the creation, modification, and deletion of user groups is a critical security measure to detect unauthorized privilege escalation or tampering with access controls.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", - "platform": "Terraform", - "descriptionID": "3f6ba6dd", - "cloudProvider": "oci", - "cwe": "778", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "3f6ba6dd-fa6d-45b4-8b27-120b7ebb4d0f", + "queryName": "Beta - Event Rule for IAM Group Changes is Missing", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to IAM groups. Auditing the creation, modification, and deletion of user groups is a critical security measure to detect unauthorized privilege escalation or tampering with access controls.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "3f6ba6dd", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From b7cbb18a7e9d4ee4d5958717b95b79c46b06162a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:35 +0100 Subject: [PATCH 568/900] fix(metadata): align riskScore to severity for oci_iam_password_policy_length --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json b/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json index 0bf9213d405..190d772a3fa 100644 --- a/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "ef7a0923-a4e6-4aec-921b-1b4e45463fb6", - "queryName": "Beta - OCI IAM Password Minimum Length", - "severity": "MEDIUM", - "category": "Identity and Access Management", - "descriptionText": "The IAM password policy allows passwords shorter than 14 characters. According to CIS Benchmarks, the 'minimum_password_length' in 'oci_identity_authentication_policy' should be set to 14 or greater.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/identity_authentication_policy", - "platform": "Terraform", - "descriptionID": "ef7a0923", - "cloudProvider": "oci", - "cwe": "521", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "ef7a0923-a4e6-4aec-921b-1b4e45463fb6", + "queryName": "Beta - OCI IAM Password Minimum Length", + "severity": "MEDIUM", + "category": "Identity and Access Management", + "descriptionText": "The IAM password policy allows passwords shorter than 14 characters. According to CIS Benchmarks, the 'minimum_password_length' in 'oci_identity_authentication_policy' should be set to 14 or greater.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/identity_authentication_policy", + "platform": "Terraform", + "descriptionID": "ef7a0923", + "cloudProvider": "oci", + "cwe": "521", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 1d95c4db4edb1fed93437527eabb35fcd6bb73d1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:37 +0100 Subject: [PATCH 569/900] fix(metadata): align riskScore to severity for oci_iam_policy_change_event_rule_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json index 160bb0057f8..568498c6842 100644 --- a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "a151d9a0-d626-447f-beab-11d53aeb0f2b", - "queryName": "Beta - Event Rule for IAM Policy Changes is Missing", - "severity": "HIGH", - "category": "Access Control", - "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to IAM policies. Auditing the creation, modification, and deletion of IAM policies is a critical security measure to detect unauthorized changes to permissions within the tenancy.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", - "platform": "Terraform", - "descriptionID": "a151d9a0", - "cloudProvider": "oci", - "cwe": "778", - "riskScore": 4.0, - "experimental": "true" +{ + "id": "a151d9a0-d626-447f-beab-11d53aeb0f2b", + "queryName": "Beta - Event Rule for IAM Policy Changes is Missing", + "severity": "HIGH", + "category": "Access Control", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to IAM policies. Auditing the creation, modification, and deletion of IAM policies is a critical security measure to detect unauthorized changes to permissions within the tenancy.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "a151d9a0", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": "6.0", + "experimental": "true" } \ No newline at end of file From f8f5e9a45ef68f083ba3b819862788ac45d5692e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:39 +0100 Subject: [PATCH 570/900] fix(metadata): align riskScore to severity for oci_iam_user_change_event_rule_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json index 463e6e831de..36349ecdc00 100644 --- a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "b1405757-feb9-4218-b685-ff53775ddf48", - "queryName": "Beta - Event Rule for IAM User Changes is Missing", - "severity": "HIGH", - "category": "Access Control", - "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to IAM users. Auditing the full lifecycle of user accounts (creation, modification, deletion, enable/disable) is a critical security measure to detect unauthorized account creation or privilege changes.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", - "platform": "Terraform", - "descriptionID": "b1405757", - "cloudProvider": "oci", - "cwe": "778", - "riskScore": 6.0, - "experimental": "true" +{ + "id": "b1405757-feb9-4218-b685-ff53775ddf48", + "queryName": "Beta - Event Rule for IAM User Changes is Missing", + "severity": "HIGH", + "category": "Access Control", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to IAM users. Auditing the full lifecycle of user accounts (creation, modification, deletion, enable/disable) is a critical security measure to detect unauthorized account creation or privilege changes.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "b1405757", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": "6.0", + "experimental": "true" } \ No newline at end of file From 4fe1114c1c7bf2af5f0221c73315a6e7736b28b7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:40 +0100 Subject: [PATCH 571/900] fix(metadata): align riskScore to severity for oci_idp_change_event_rule_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json index 2b666efa371..c5994d2d53f 100644 --- a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "0a077b15-dc77-4490-810b-4e34f1b55500", - "queryName": "Beta - Event Rule for Identity Provider Changes is Missing", - "severity": "MEDIUM", - "category": "Access Control", - "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Identity Providers. Monitoring these changes is critical for detecting potentially malicious activity, such as the addition of an unauthorized external identity provider.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", - "platform": "Terraform", - "descriptionID": "0a077b15", - "cloudProvider": "oci", - "cwe": "778", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "0a077b15-dc77-4490-810b-4e34f1b55500", + "queryName": "Beta - Event Rule for Identity Provider Changes is Missing", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Identity Providers. Monitoring these changes is critical for detecting potentially malicious activity, such as the addition of an unauthorized external identity provider.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "0a077b15", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 42f472196c6203dc309ffdb4c0d341c722b4d6f9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:42 +0100 Subject: [PATCH 572/900] fix(metadata): align riskScore to severity for oci_idp_group_mapping_change_event_rule_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json index 077810fbad5..e985e70fecc 100644 --- a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "1f106aa1-a994-4a11-afbc-109f31947d6a", - "queryName": "Beta - Event Rule for IdP Group Mapping Changes is Missing", - "severity": "MEDIUM", - "category": "Access Control", - "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Identity Provider (IdP) group mappings. Auditing these changes is vital for detecting unauthorized modifications to user group permissions.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", - "platform": "Terraform", - "descriptionID": "1f106aa1", - "cloudProvider": "oci", - "cwe": "778", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "1f106aa1-a994-4a11-afbc-109f31947d6a", + "queryName": "Beta - Event Rule for IdP Group Mapping Changes is Missing", + "severity": "MEDIUM", + "category": "Access Control", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Identity Provider (IdP) group mappings. Auditing these changes is vital for detecting unauthorized modifications to user group permissions.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "1f106aa1", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 3d30e2fb997520c21e2a4eb52764ff13c30d3688 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:43 +0100 Subject: [PATCH 573/900] fix(metadata): align riskScore to severity for oci_instance_transit_encryption --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json b/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json index edf93c76dbd..130967613df 100644 --- a/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "c29ef8f7-33bc-4788-9085-3a561c91f7d1", - "queryName": "Beta - OCI Instance In-Transit Encryption Disabled", - "severity": "MEDIUM", - "category": "Encryption", - "descriptionText": "Compute instances should have in-transit encryption enabled for data moving between the instance and block storage. This is configured via 'is_pv_encryption_in_transit_enabled' in the 'launch_options' block.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_instance#is_pv_encryption_in_transit_enabled", - "platform": "Terraform", - "descriptionID": "c29ef8f7", - "cloudProvider": "oci", - "cwe": "311", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "c29ef8f7-33bc-4788-9085-3a561c91f7d1", + "queryName": "Beta - OCI Instance In-Transit Encryption Disabled", + "severity": "MEDIUM", + "category": "Encryption", + "descriptionText": "Compute instances should have in-transit encryption enabled for data moving between the instance and block storage. This is configured via 'is_pv_encryption_in_transit_enabled' in the 'launch_options' block.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_instance#is_pv_encryption_in_transit_enabled", + "platform": "Terraform", + "descriptionID": "c29ef8f7", + "cloudProvider": "oci", + "cwe": "311", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 5b43c447352d95f60dec861568b780f80a346943 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:44 +0100 Subject: [PATCH 574/900] fix(metadata): align riskScore to severity for oci_local_user_authentication_event_rule_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json index feef0d4cbcf..131b29366a6 100644 --- a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "e0c61731-a692-44d8-bbf2-8279985a4e41", - "queryName": "Beta - Event Rule for Local User Authentication is Missing", - "severity": "HIGH", - "category": "Access Control", - "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on authentication events from local IAM users. Auditing local user logins is a critical security measure to detect unauthorized access attempts and compromised credentials.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", - "platform": "Terraform", - "descriptionID": "e0c61731", - "cloudProvider": "oci", - "cwe": "778", - "riskScore": 6.0, - "experimental": "true" +{ + "id": "e0c61731-a692-44d8-bbf2-8279985a4e41", + "queryName": "Beta - Event Rule for Local User Authentication is Missing", + "severity": "HIGH", + "category": "Access Control", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on authentication events from local IAM users. Auditing local user logins is a critical security measure to detect unauthorized access attempts and compromised credentials.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "e0c61731", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": "6.0", + "experimental": "true" } \ No newline at end of file From 58f0c9eaea9263a76fbec0b8d85c868a7cfd01d3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:46 +0100 Subject: [PATCH 575/900] fix(metadata): align riskScore to severity for oci_network_gateway_change_event_rule_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json index f9bfda34c12..7b120e77164 100644 --- a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "e3ade454-28a1-4a0c-9905-b73e82a648c0", - "queryName": "Beta - Event Rule for Network Gateway Changes is Missing", - "severity": "MEDIUM", - "category": "Networking and Firewall", - "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to all types of Network Gateways (Internet, NAT, Service, DRG, etc.). Auditing gateway changes is crucial for detecting unauthorized modifications to network ingress/egress points.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", - "platform": "Terraform", - "descriptionID": "e3ade454", - "cloudProvider": "oci", - "cwe": "778", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "e3ade454-28a1-4a0c-9905-b73e82a648c0", + "queryName": "Beta - Event Rule for Network Gateway Changes is Missing", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to all types of Network Gateways (Internet, NAT, Service, DRG, etc.). Auditing gateway changes is crucial for detecting unauthorized modifications to network ingress/egress points.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "e3ade454", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 1aeeb4a12431834e4149e98e564f45f0a69517b0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:47 +0100 Subject: [PATCH 576/900] fix(metadata): align riskScore to severity for oci_notification_topic_without_subscription --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json index efcddeb3468..0d8b32d31f7 100644 --- a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "8e61709a-7ba2-4d51-a8ef-796a45e7c82c", - "queryName": "Beta - Notification Topic Without Subscription", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that OCI notification topics have at least one active subscription to deliver alerts. A topic without a subscription receives messages but does not send them to any destination, rendering monitoring alerts ineffective.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/ons_subscription", - "platform": "Terraform", - "descriptionID": "8e61709a", - "cloudProvider": "oci", - "cwe": "778", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "8e61709a-7ba2-4d51-a8ef-796a45e7c82c", + "queryName": "Beta - Notification Topic Without Subscription", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that OCI notification topics have at least one active subscription to deliver alerts. A topic without a subscription receives messages but does not send them to any destination, rendering monitoring alerts ineffective.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/ons_subscription", + "platform": "Terraform", + "descriptionID": "8e61709a", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 6790fce597e49621846f1c5d36a5717dd13c8c93 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:48 +0100 Subject: [PATCH 577/900] fix(metadata): align riskScore to severity for oci_nsg_change_event_rule_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json index 6fae1ae4d0b..be7f05cf865 100644 --- a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "a1b080a7-8d58-4018-a14d-17beb72f5cef", - "queryName": "Beta - Event Rule for NSG Changes is Missing", - "severity": "MEDIUM", - "category": "Networking and Firewall", - "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Network Security Groups (NSGs). Auditing changes to NSGs is critical for detecting unauthorized modifications to network micro-segmentation rules that could expose services.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", - "platform": "Terraform", - "descriptionID": "a1b080a7", - "cloudProvider": "oci", - "cwe": "778", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "a1b080a7-8d58-4018-a14d-17beb72f5cef", + "queryName": "Beta - Event Rule for NSG Changes is Missing", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Network Security Groups (NSGs). Auditing changes to NSGs is critical for detecting unauthorized modifications to network micro-segmentation rules that could expose services.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "a1b080a7", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 07b55b4a4a58412d572326ef917f18f68c4263a1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:50 +0100 Subject: [PATCH 578/900] fix(metadata): align riskScore to severity for oci_objectstorage_bucket_logging_enabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json index 65e63531975..1ec8ee194bb 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "5ecf7b51-8c4b-4911-9d59-1f7f6b9a2143", - "queryName": "Beta - Object Storage Bucket Logging Disabled", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that OCI Object Storage buckets have object event emission enabled, which is crucial for write-level logging and security auditing.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/objectstorage_bucket#object_events_enabled", - "platform": "Terraform", - "descriptionID": "5ecf7b51", - "cloudProvider": "oci", - "cwe": "223", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "5ecf7b51-8c4b-4911-9d59-1f7f6b9a2143", + "queryName": "Beta - Object Storage Bucket Logging Disabled", + "severity": "MEDIUM", + "category": "Observability", + "descriptionText": "Ensures that OCI Object Storage buckets have object event emission enabled, which is crucial for write-level logging and security auditing.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/objectstorage_bucket#object_events_enabled", + "platform": "Terraform", + "descriptionID": "5ecf7b51", + "cloudProvider": "oci", + "cwe": "223", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From b99bef16b5be2e413ab83b4e8b18230bcfd6823f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:52 +0100 Subject: [PATCH 579/900] fix(metadata): align riskScore to severity for oci_objectstorage_bucket_versioning_disabled --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json index 51421402e47..6f597340f2f 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "72b1c53c-619e-4e0a-937a-9af24cae69df", - "queryName": "Beta - Object Storage Bucket Versioning Disabled", - "severity": "MEDIUM", - "category": "Data Security", - "descriptionText": "Ensures that OCI Object Storage buckets have versioning enabled. Versioning protects against accidental deletion or overwriting of objects by keeping a history of all object versions.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/objectstorage_bucket#versioning", - "platform": "Terraform", - "descriptionID": "72b1c53c", - "cloudProvider": "oci", - "cwe": "668", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "72b1c53c-619e-4e0a-937a-9af24cae69df", + "queryName": "Beta - Object Storage Bucket Versioning Disabled", + "severity": "MEDIUM", + "category": "Data Security", + "descriptionText": "Ensures that OCI Object Storage buckets have versioning enabled. Versioning protects against accidental deletion or overwriting of objects by keeping a history of all object versions.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/objectstorage_bucket#versioning", + "platform": "Terraform", + "descriptionID": "72b1c53c", + "cloudProvider": "oci", + "cwe": "668", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 84a5dc74475000c4ed2db9398ca6cd6d51a4e99e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:57 +0100 Subject: [PATCH 580/900] fix(metadata): align riskScore to severity for oci_resource_created_in_root_compartment --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json index db1c83524d3..274501f30ae 100644 --- a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json +++ b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "eb205044-d89b-40ac-9846-2e5993e091ab", - "queryName": "Beta - Resource Created In Root Compartment", - "severity": "HIGH", - "category": "Best Practices", - "descriptionText": "Ensures that resources are not created directly in the root compartment (tenancy). Following the principle of least privilege and separation of concerns, resources should be organized into dedicated child compartments.", - "descriptionUrl": "https://docs.oracle.com/en-us/iaas/Content/cloud-adoption-framework/iam-security-structure.htm", - "platform": "Terraform", - "descriptionID": "eb205044", - "cloudProvider": "oci", - "cwe": "284", - "riskScore": 6.0, - "experimental": "true" +{ + "id": "eb205044-d89b-40ac-9846-2e5993e091ab", + "queryName": "Beta - Resource Created In Root Compartment", + "severity": "HIGH", + "category": "Best Practices", + "descriptionText": "Ensures that resources are not created directly in the root compartment (tenancy). Following the principle of least privilege and separation of concerns, resources should be organized into dedicated child compartments.", + "descriptionUrl": "https://docs.oracle.com/en-us/iaas/Content/cloud-adoption-framework/iam-security-structure.htm", + "platform": "Terraform", + "descriptionID": "eb205044", + "cloudProvider": "oci", + "cwe": "284", + "riskScore": "6.0", + "experimental": "true" } \ No newline at end of file From f6ccce71ac0388f8356bf33e9ace1b2d67617431 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:23:59 +0100 Subject: [PATCH 581/900] fix(metadata): align riskScore to severity for oci_route_table_change_event_rule_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json index 080eb902f0b..b0bc83afbed 100644 --- a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "b3af1ce8-5711-4304-b1db-17b658629df2", - "queryName": "Beta - Event Rule for Route Table Changes is Missing", - "severity": "MEDIUM", - "category": "Networking and Firewall", - "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Route Tables. Auditing changes to route tables is critical for detecting unauthorized network path modifications that could lead to traffic interception or service disruption.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", - "platform": "Terraform", - "descriptionID": "b3af1ce8", - "cloudProvider": "oci", - "cwe": "778", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "b3af1ce8-5711-4304-b1db-17b658629df2", + "queryName": "Beta - Event Rule for Route Table Changes is Missing", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Route Tables. Auditing changes to route tables is critical for detecting unauthorized network path modifications that could lead to traffic interception or service disruption.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "b3af1ce8", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From 5813c18c42ce75f5d835281069cd4ff9f6c70048 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:24:01 +0100 Subject: [PATCH 582/900] fix(metadata): align riskScore to severity for oci_security_list_change_event_rule_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json index b9f61de2141..fbe51092bbe 100644 --- a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "a5dfa109-1f7d-4077-8d10-41247bfcf922", - "queryName": "Beta - Event Rule for Security List Changes is Missing", - "severity": "MEDIUM", - "category": "Networking and Firewall", - "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Security Lists. Auditing changes to these network ACLs is critical for detecting unauthorized modifications that could expose services to unintended traffic.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", - "platform": "Terraform", - "descriptionID": "a5dfa109", - "cloudProvider": "oci", - "cwe": "778", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "a5dfa109-1f7d-4077-8d10-41247bfcf922", + "queryName": "Beta - Event Rule for Security List Changes is Missing", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Security Lists. Auditing changes to these network ACLs is critical for detecting unauthorized modifications that could expose services to unintended traffic.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "a5dfa109", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From f66d02a9564911cea1950922d3defa19fea3d413 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:24:03 +0100 Subject: [PATCH 583/900] fix(metadata): align riskScore to severity for oci_subnet_flow_logging_disabled --- .../oci/oci_subnet_flow_logging_disabled/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json index f62afaa45da..aa15094a4b0 100644 --- a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/metadata.json @@ -9,6 +9,6 @@ "descriptionID": "30d3bb83", "cloudProvider": "oci", "cwe": "778", - "riskScore": 6.0, + "riskScore": "6.0", "experimental": "true" } \ No newline at end of file From b65f1f5e09cacf0dbbbfc90b0fd83e7aa5dd7a56 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:24:04 +0100 Subject: [PATCH 584/900] fix(metadata): align riskScore to severity for oci_vcn_change_event_rule_missing --- .../metadata.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json index dc73dd6c9c0..0d1a4009740 100644 --- a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/metadata.json @@ -1,14 +1,14 @@ -{ - "id": "419bb431-bf37-4e5d-bda6-af3750e808e4", - "queryName": "Beta - Event Rule for VCN Changes is Missing", - "severity": "MEDIUM", - "category": "Networking and Firewall", - "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Virtual Cloud Networks (VCNs). Auditing the creation, modification, and deletion of VCNs is important for detecting unauthorized network changes that could impact security posture.", - "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", - "platform": "Terraform", - "descriptionID": "419bb431", - "cloudProvider": "oci", - "cwe": "778", - "riskScore": 3.0, - "experimental": "true" +{ + "id": "419bb431-bf37-4e5d-bda6-af3750e808e4", + "queryName": "Beta - Event Rule for VCN Changes is Missing", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensures that an OCI event rule is configured to monitor and alert on changes to Virtual Cloud Networks (VCNs). Auditing the creation, modification, and deletion of VCNs is important for detecting unauthorized network changes that could impact security posture.", + "descriptionUrl": "https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/events_rule", + "platform": "Terraform", + "descriptionID": "419bb431", + "cloudProvider": "oci", + "cwe": "778", + "riskScore": "3.0", + "experimental": "true" } \ No newline at end of file From d84f3c4353185fd423c351083ffafdc5f39140b4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:27:57 +0100 Subject: [PATCH 585/900] fix(rego): add searchLine to azure_app_service_application_insights_not_configured --- .../query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego index 8cbaef5d9e8..df488173fe3 100644 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib targets := { From 55b643f93c187c5b080ea30be63550786cae867c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:27:58 +0100 Subject: [PATCH 586/900] fix(rego): add searchLine to azure_app_service_http_logs_disabled --- .../azure/azure_app_service_http_logs_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego index 9d0be296f83..f5914643bc9 100644 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib targets := {"azurerm_linux_web_app", "azurerm_windows_web_app"} From c5582870a6dbf9344e73c6393d353df17862a6b5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:27:59 +0100 Subject: [PATCH 587/900] fix(rego): add searchLine to azure_backup_vault_cross_region_restore_disabled --- .../azure_backup_vault_cross_region_restore_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego index 9b22682a4be..f1b06503a2c 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: Missing Configuration. From ff2abb98a1d9d51a90787d7d18d51a6d37d1bb72 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:00 +0100 Subject: [PATCH 588/900] fix(rego): add searchLine to azure_backup_vault_infrastructure_encryption_disabled --- .../query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego index 26e9ed31482..4a7c17436f9 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: The 'identity' block is missing, which is required to manage advanced encryption. From 32b2ead0a4e38bbadfeb678d4c9d0773fbb7c4c7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:02 +0100 Subject: [PATCH 589/900] fix(rego): add searchLine to azure_bastion_host_missing --- .../terraform/azure/azure_bastion_host_missing/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego b/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego index 6effebc737b..7285b599b12 100644 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: A VNet exists, but no azurerm_bastion_host resource exists in the document. From 6c8eb51f82e8235f524d05ee3991c4b4d447c2a8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:03 +0100 Subject: [PATCH 590/900] fix(rego): add searchLine to azure_elastic_san_public_access_enabled --- .../azure/azure_elastic_san_public_access_enabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego index 61bbfc77306..536bb1b9424 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: The 'network_rule' block is not defined. From cf940547e27f8aaa171e163a1004c4fa9f9e8971 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:04 +0100 Subject: [PATCH 591/900] fix(rego): add searchLine to azure_iot_hub_defender_disabled --- .../terraform/azure/azure_iot_hub_defender_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego index 89f9d92cca4..9a907c6395a 100644 --- a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: IoT Hub without an associated security solution (azurerm_iot_security_solution). From d853a4df39d0b23978bbe85fe772fbadfd9fdab8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:06 +0100 Subject: [PATCH 592/900] fix(rego): add searchLine to azure_key_vault_key_rotation_disabled --- .../azure/azure_key_vault_key_rotation_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego index e6331167f33..51c87f675dd 100644 --- a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: The Key Vault key does not have a rotation policy configured. From 8fd6fbc7b0c43fb2be3b4d778a5d042155be4549 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:07 +0100 Subject: [PATCH 593/900] fix(rego): add searchLine to azure_managed_lustre_cmk_encryption_disabled --- .../azure_managed_lustre_cmk_encryption_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego index 9347a6f0a1f..5564df2db71 100644 --- a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: The 'encryption_key' block is not defined. From e78fc5e11e4fc61c8ff3f5a9a884eeeefde49f2f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:09 +0100 Subject: [PATCH 594/900] fix(rego): add searchLine to azure_mysql_audit_log_enabled_manual --- .../azure/azure_mysql_audit_log_enabled_manual/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego index 8c719c49278..24fe8627f71 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib targets := {"azurerm_mssql_server", "azurerm_mysql_flexible_server"} From 1910ec27585d144d3fcd37107f7ca9dcbc6c23d4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:10 +0100 Subject: [PATCH 595/900] fix(rego): add searchLine to azure_mysql_audit_log_events_connection_manual --- .../azure_mysql_audit_log_events_connection_manual/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego index 5d64544e5a2..6534ec55bdc 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib targets := {"azurerm_mssql_server", "azurerm_mysql_flexible_server"} From 497a487d2b80d0dcbd41663597d9774784105560 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:12 +0100 Subject: [PATCH 596/900] fix(rego): add searchLine to azure_paas_private_endpoint_missing --- .../azure/azure_paas_private_endpoint_missing/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego index 2aab0d37bb3..182970378cb 100644 --- a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib targets := { From 635b0ebe1cfca0f27f96fa716b2b14b38fb05287 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:13 +0100 Subject: [PATCH 597/900] fix(rego): add searchLine to azure_production_workload_basic_consumption_sku --- .../azure_production_workload_basic_consumption_sku/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego index 486843a915d..7cc926ef599 100644 --- a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: Azure Service Plan using Basic (B), Free (F), or Consumption (Y1) SKU. From 7451fe9c74bc6948b6c4ad179d6ccb09b159ddf1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:15 +0100 Subject: [PATCH 598/900] fix(rego): add searchLine to azure_recovery_services_vault_cross_region_restore_disabled --- .../query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego index de7299118c7..8ba9c497f22 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: The 'cross_region_restore_enabled' attribute is missing. From 23e53cbd6edb31d6d47be563bd17c631e60cb233 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:16 +0100 Subject: [PATCH 599/900] fix(rego): add searchLine to azure_recovery_services_vault_infrastructure_encryption_disabled --- .../query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego index 9472a676075..81589034907 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: The 'encryption' block is not defined. From 9f2504db1cfa10e07b508b51eb6ab1004c5a209a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:17 +0100 Subject: [PATCH 600/900] fix(rego): add searchLine to azure_storage_account_geo_redundancy_disabled --- .../azure_storage_account_geo_redundancy_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego index 04c75160959..5bcd3ffbdcf 100644 --- a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib geo_redundant_types := {"GRS", "RAGRS", "GZRS", "RAGZRS"} From 7212e6258fe960b53f1c6fd301a79ae62539c112 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:19 +0100 Subject: [PATCH 601/900] fix(rego): add searchLine to azure_storage_account_infrastructure_encryption_disabled --- .../query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego index 46e82f114ad..08c46aa595e 100644 --- a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: The 'infrastructure_encryption_enabled' attribute is missing. From ad2eadaf3891535660da69d1efdb65c30312818e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:20 +0100 Subject: [PATCH 602/900] fix(rego): add searchLine to azure_storage_account_read_only_lock_missing --- .../azure_storage_account_read_only_lock_missing/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego index addf9d7041b..2013114368b 100644 --- a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib has_readonly_lock(doc, sa_id) { From 3e091a0c677de4f54efc1f16c5a9f6d4ba77dab9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:21 +0100 Subject: [PATCH 603/900] fix(rego): add searchLine to azure_storage_account_versioning_disabled --- .../azure/azure_storage_account_versioning_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego index af6c3e5654f..fd1046ae58f 100644 --- a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # CASE 1: The complete 'blob_properties' block is missing. From 92a3d9c6cbb9201157c4759843aa4f7631e780d4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:23 +0100 Subject: [PATCH 604/900] fix(rego): add searchLine to azure_storage_blob_logging_disabled --- .../azure/azure_storage_blob_logging_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego index 3366b584bd2..7c068a0df48 100644 --- a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib is_target_linked(target, sa_name) { From 4d404300adeddda2d7b71545a7d7950906c7e0ec Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:24 +0100 Subject: [PATCH 605/900] fix(rego): add searchLine to azure_storage_container_immutability_not_locked --- .../azure_storage_container_immutability_not_locked/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego index 00b51f85924..f041b700963 100644 --- a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: The 'locked' attribute is not defined (Default is false/unlocked). From 7e87d74c8364469ae14e44c292cbdfc77376bcea Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:25 +0100 Subject: [PATCH 606/900] fix(rego): add searchLine to azure_storage_queue_logging_disabled --- .../azure/azure_storage_queue_logging_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego index b77e675c4bc..212e701545f 100644 --- a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib is_logging_valid(logging) { From be9ea92dc8a5687c81db0b9b1e6fd1dc684e6cbd Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:26 +0100 Subject: [PATCH 607/900] fix(rego): add searchLine to azure_storage_table_logging_disabled --- .../azure/azure_storage_table_logging_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego index 33917f2bcd2..3b5defba49b 100644 --- a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib is_target_linked(target, sa_name) { From e3a29457dcac3dc87a44286f3bdafeedffed7bec Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:28 +0100 Subject: [PATCH 608/900] fix(rego): add searchLine to gcp_access_approval_disabled --- .../terraform/gcp/gcp_access_approval_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego b/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego index efc85cd9f2b..5eb474be768 100644 --- a/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # CASE 1: Project without Access Approval configuration. From c88803baced746779d57309f36a756c4321ab51b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:29 +0100 Subject: [PATCH 609/900] fix(rego): add searchLine to gcp_api_key_api_targets_missing --- .../terraform/gcp/gcp_api_key_api_targets_missing/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego index 128870a4d60..b80f1d8daf6 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # CASE 1: The 'restrictions' block does not exist. From 224c9e9f6b8ff575fa363ed520af9c69fb326518 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:31 +0100 Subject: [PATCH 610/900] fix(rego): add searchLine to gcp_api_key_restrictions_manual --- .../terraform/gcp/gcp_api_key_restrictions_manual/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego index 775874fadec..5c9be6360ba 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # CASO 1: No hay restricciones definidas. From c0fdd462def768aabe41e11433cbf1d0d160f88b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:32 +0100 Subject: [PATCH 611/900] fix(rego): add searchLine to gcp_app_engine_https_enforcement_manual --- .../gcp/gcp_app_engine_https_enforcement_manual/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego index 17683e522ca..cd06bace053 100644 --- a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib ensure_array(x) = x { is_array(x) } From e6dfc48eb88c1d7a87aa01bb90bd37d31f878f95 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:33 +0100 Subject: [PATCH 612/900] fix(rego): add searchLine to gcp_compute_logging_service_disabled --- .../gcp/gcp_compute_logging_service_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego index d6635bb0742..ea451702172 100644 --- a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: The 'metadata' block does not exist. From dbd5d08787c721e754ffdc51913b5958769ea58b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:34 +0100 Subject: [PATCH 613/900] fix(rego): add searchLine to gcp_gke_default_service_account_used --- .../gcp/gcp_gke_default_service_account_used/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego index e2f1e6b1003..4641ae0da74 100644 --- a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: Service Account missing in google_container_cluster. From e5d50102a693105d64e074e77202df9ea5363a57 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:36 +0100 Subject: [PATCH 614/900] fix(rego): add searchLine to gcp_gke_metadata_server_disabled --- .../terraform/gcp/gcp_gke_metadata_server_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego index ef477f34506..c44fa685cce 100644 --- a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: 'workload_metadata_config' missing in google_container_cluster From b32d76bdc4c17972dfa5b54ebcd365ed300b3e10 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:37 +0100 Subject: [PATCH 615/900] fix(rego): add searchLine to gcp_gke_sandbox_disabled --- assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego index e37255d0743..9bedcb2f493 100644 --- a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: 'sandbox_config' block missing in google_container_cluster. From 04c397f0f6e4f423744fb65b2ea879a3df90f64d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:39 +0100 Subject: [PATCH 616/900] fix(rego): add searchLine to gcp_gke_secrets_encryption_cmek_disabled --- .../gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego index c7129fff397..ec17cc8d57a 100644 --- a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: 'database_encryption' block missing. From 4b04638f19b0a1dce414ff0d6579c9be862edf54 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:40 +0100 Subject: [PATCH 617/900] fix(rego): add searchLine to gcp_http_load_balancer_logging_disabled --- .../gcp/gcp_http_load_balancer_logging_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego index 4477185b7c6..fb8c4c6924b 100644 --- a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # REGLA 1: Bloque 'log_config' ausente. From 19a229bfb600b260fbe1ad6258338fc6d2590bfd Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:41 +0100 Subject: [PATCH 618/900] fix(rego): add searchLine to gcp_iap_backend_service_disabled --- .../terraform/gcp/gcp_iap_backend_service_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego index b4b25a906fe..37a83794a37 100644 --- a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib # REGLA 1: El bloque 'iap' está ausente en google_compute_backend_service. From bb02b501a7da9a1cb8760c8370e866363cd9a765 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:43 +0100 Subject: [PATCH 619/900] fix(rego): add searchLine to gcp_sql_postgresql_log_error_verbosity_verbose --- .../gcp_sql_postgresql_log_error_verbosity_verbose/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego index 9a7d4410a0d..710d3ea7c44 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib ensure_array(x) = x { is_array(x) } From 38729ac2e6ce2cf8be3049643b2ee5a51ed4edc5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:44 +0100 Subject: [PATCH 620/900] fix(rego): add searchLine to gcp_sql_postgresql_log_statement_improperly_set --- .../gcp_sql_postgresql_log_statement_improperly_set/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego index 0abb99d85a2..f002dde382a 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import data.generic.terraform as tf_lib ensure_array(x) = x { is_array(x) } From a273d7ba0a214c2889b4db373e70f248ef37959e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:45 +0100 Subject: [PATCH 621/900] fix(rego): add searchLine to ibm_activity_tracker_global_events_disabled --- .../ibm/ibm_activity_tracker_global_events_disabled/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego index 2f71acd96dd..3104c2dfd3c 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego @@ -14,7 +14,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.ibm", + "searchKey": "provider.ibm", + "searchLine": common_lib.build_search_line(["provider", "ibm"], []), "issueType": "MissingAttribute", "keyExpectedValue": "An 'ibm_resource_instance' with service='activity-tracker' should exist", "keyActualValue": "No 'ibm_resource_instance' for service 'activity-tracker' was found", From 46349913c8b413264e1039e263428bc6a20345c2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:46 +0100 Subject: [PATCH 622/900] fix(rego): add searchLine to ibm_activity_tracker_platform_logs_disabled --- .../ibm/ibm_activity_tracker_platform_logs_disabled/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego index 7fb022a7f88..566c736f2e2 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego @@ -14,7 +14,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.ibm", + "searchKey": "provider.ibm", + "searchLine": common_lib.build_search_line(["provider", "ibm"], []), "issueType": "MissingAttribute", "keyExpectedValue": "An 'ibm_resource_instance' with service='activity-tracker' should exist", "keyActualValue": "No 'ibm_resource_instance' for service 'activity-tracker' was found", From c618b8d12769e50cb50602dd8e7b224eb096f2eb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:51 +0100 Subject: [PATCH 623/900] fix(rego): add searchLine to ibm_iam_account_mfa_disabled --- .../terraform/ibm/ibm_iam_account_mfa_disabled/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego index a2a2e9ebd82..e1cfb636772 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego @@ -13,7 +13,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.ibm", + "searchKey": "provider.ibm", + "searchLine": common_lib.build_search_line(["provider", "ibm"], []), "issueType": "MissingAttribute", "keyExpectedValue": "Resource 'ibm_iam_account_settings' should exist to enforce MFA", "keyActualValue": "Resource 'ibm_iam_account_settings' is missing in this IBM configuration", From f82a7068898d8b77f5e1f0da96a41073ed8eaa31 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:56 +0100 Subject: [PATCH 624/900] fix(rego): add searchLine to oci_cloud_guard_problem_event_rule_missing --- .../oci/oci_cloud_guard_problem_event_rule_missing/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/query.rego index 242b379619d..7278f61dfca 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/query.rego @@ -16,7 +16,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "An 'oci_events_rule' for Cloud Guard problems should exist in the project", "keyActualValue": "No 'oci_events_rule' is configured to audit Cloud Guard problems", From 4779a7a7020481b51d988faf1e539170dae077d8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:58 +0100 Subject: [PATCH 625/900] fix(rego): add searchLine to oci_cloud_guard_root_compartment_disabled --- .../oci/oci_cloud_guard_root_compartment_disabled/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego index 50852570508..a2087acc3d1 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego @@ -13,7 +13,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "Resource 'oci_cloud_guard_configuration' should exist to enable Cloud Guard", "keyActualValue": "Resource 'oci_cloud_guard_configuration' is missing", From 3e1f48feb522d086de80abb009aef7e0f53cd631 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:28:59 +0100 Subject: [PATCH 626/900] fix(rego): add searchLine to oci_compute_secure_boot_disabled --- .../terraform/oci/oci_compute_secure_boot_disabled/query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego index 845d60034fa..3095e105efc 100644 --- a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego @@ -1,5 +1,7 @@ package Cx +import data.generic.common as common_lib + # RULE 1: The 'platform_config' block is missing entirely. CxPolicy[result] { instance := input.document[i].resource.oci_core_instance[instance_name] From f4e863ced384762431523de6ef184f5d3f38c907 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:29:01 +0100 Subject: [PATCH 627/900] fix(rego): add searchLine to oci_default_tags_not_defined --- .../terraform/oci/oci_default_tags_not_defined/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_default_tags_not_defined/query.rego b/assets/queries/terraform/oci/oci_default_tags_not_defined/query.rego index 7d02815c15c..d816de85896 100644 --- a/assets/queries/terraform/oci/oci_default_tags_not_defined/query.rego +++ b/assets/queries/terraform/oci/oci_default_tags_not_defined/query.rego @@ -12,7 +12,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "At least one 'oci_identity_tag_default' resource should exist to define a default tagging policy", "keyActualValue": "No 'oci_identity_tag_default' resource was found in the configuration", From 41193b359a909b65968176d7cf34b6b5e2aa2fac Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:29:02 +0100 Subject: [PATCH 628/900] fix(rego): add searchLine to oci_iam_group_change_event_rule_missing --- .../oci/oci_iam_group_change_event_rule_missing/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego index d8e3f3902f3..df0dd3b0aff 100644 --- a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego @@ -23,7 +23,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "An 'oci_events_rule' for IAM group changes should exist", "keyActualValue": "No 'oci_events_rule' found for IAM group changes", From 68208229bc786d09032480cb4e2cab863fb9cf76 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:29:05 +0100 Subject: [PATCH 629/900] fix(rego): add searchLine to oci_iam_policy_change_event_rule_missing --- .../oci/oci_iam_policy_change_event_rule_missing/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego index b51144a73ee..c1f51e6e269 100644 --- a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego @@ -22,7 +22,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "An 'oci_events_rule' for IAM Policy changes should exist", "keyActualValue": "No 'oci_events_rule' found for IAM Policy changes", From 40a5cde9eb68a04b4031adcc8b6a38a03eee0aff Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:29:07 +0100 Subject: [PATCH 630/900] fix(rego): add searchLine to oci_iam_user_change_event_rule_missing --- .../oci/oci_iam_user_change_event_rule_missing/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego index af9fd41e8e7..8d109df061c 100644 --- a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego @@ -24,7 +24,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "An 'oci_events_rule' for IAM User changes (create, update, delete, enable, disable) should exist", "keyActualValue": "No 'oci_events_rule' found for IAM User changes", From f948a80517d5eb9dcf8b29ba21bd801fe2094fa0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:29:09 +0100 Subject: [PATCH 631/900] fix(rego): add searchLine to oci_idp_change_event_rule_missing --- .../terraform/oci/oci_idp_change_event_rule_missing/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego index 5b650d7bc6a..82fd26b90f9 100644 --- a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego @@ -17,7 +17,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "An 'oci_events_rule' for Identity Provider changes should exist", "keyActualValue": "No 'oci_events_rule' found for Identity Provider changes", From 0f80c11255a1d02398810be1b09317dcdf977eaa Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:29:11 +0100 Subject: [PATCH 632/900] fix(rego): add searchLine to oci_idp_group_mapping_change_event_rule_missing --- .../oci_idp_group_mapping_change_event_rule_missing/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego index 18e7c22d871..d844640863e 100644 --- a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego @@ -17,7 +17,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "An 'oci_events_rule' for IdP group mapping changes should exist", "keyActualValue": "No 'oci_events_rule' found for IdP group mapping changes", From 06f845b517bef5e59a32a7c22a250015a0344955 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:29:13 +0100 Subject: [PATCH 633/900] fix(rego): add searchLine to oci_local_user_authentication_event_rule_missing --- .../query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego index 7bb5a1ce53d..8a9f9b32ba3 100644 --- a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego @@ -17,7 +17,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "An 'oci_events_rule' for local user authentication events should exist", "keyActualValue": "No 'oci_events_rule' found for local user authentication", From 7b06cf90d95fc1bdf6f2d623062c274d4bb0e162 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:29:14 +0100 Subject: [PATCH 634/900] fix(rego): add searchLine to oci_network_gateway_change_event_rule_missing --- .../oci_network_gateway_change_event_rule_missing/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego index d2e8bf40def..0a8f1dc9abf 100644 --- a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego @@ -34,7 +34,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "An 'oci_events_rule' for Network Gateway changes should exist", "keyActualValue": "No 'oci_events_rule' found for Network Gateway changes", From 6f7d4c6e66247b0d4e3a05aeaa3ed99856951207 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:29:15 +0100 Subject: [PATCH 635/900] fix(rego): add searchLine to oci_notification_topic_without_subscription --- .../oci/oci_notification_topic_without_subscription/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego index 471b4476c5e..3bd5c49babd 100644 --- a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego @@ -14,7 +14,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "At least one 'oci_ons_notification_topic' resource should exist", "keyActualValue": "No 'oci_ons_notification_topic' resource was found", From 6db269459d259f3b9fe7e40b8c7bf2077931b7bb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:29:17 +0100 Subject: [PATCH 636/900] fix(rego): add searchLine to oci_nsg_change_event_rule_missing --- .../terraform/oci/oci_nsg_change_event_rule_missing/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego index 79295221afb..b0f6ea3d8c9 100644 --- a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego @@ -22,7 +22,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "An 'oci_events_rule' for Network Security Group changes should exist", "keyActualValue": "No 'oci_events_rule' found for Network Security Group changes", From d53760b787681c43fa6f8f320bb576ebb8d1bd59 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:29:19 +0100 Subject: [PATCH 637/900] fix(rego): add searchLine to oci_resource_created_in_root_compartment --- .../oci/oci_resource_created_in_root_compartment/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/query.rego b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/query.rego index 10acdb2003a..f779d3edb59 100644 --- a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/query.rego +++ b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/query.rego @@ -1,5 +1,6 @@ package Cx +import data.generic.common as common_lib import future.keywords.in auditable_resource_types := { From ce5cb2b68dddc115e75d8a080b4cf99d57af5c04 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:29:21 +0100 Subject: [PATCH 638/900] fix(rego): add searchLine to oci_route_table_change_event_rule_missing --- .../oci/oci_route_table_change_event_rule_missing/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego index 78c6bc27730..f299c2b7fe6 100644 --- a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego @@ -22,7 +22,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "An 'oci_events_rule' for Route Table changes should exist", "keyActualValue": "No 'oci_events_rule' found for Route Table changes", From 9fb18d5768d798d7b1a18c63377b59259f5c58ee Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:29:22 +0100 Subject: [PATCH 639/900] fix(rego): add searchLine to oci_security_list_change_event_rule_missing --- .../oci/oci_security_list_change_event_rule_missing/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego index 13db46a0e07..a37133baf4c 100644 --- a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego @@ -22,7 +22,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "An 'oci_events_rule' for Security List changes should exist", "keyActualValue": "No 'oci_events_rule' found for Security List changes", From 0b000ee3593a4379f9b5edcec440d262671ff371 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:29:25 +0100 Subject: [PATCH 640/900] fix(rego): add searchLine to oci_vcn_change_event_rule_missing --- .../terraform/oci/oci_vcn_change_event_rule_missing/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego index f2223e8e8f1..7e44136b8bb 100644 --- a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego @@ -22,7 +22,8 @@ CxPolicy[result] { result := { "documentId": doc.id, - "searchKey": "provider.oci", + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", "keyExpectedValue": "An 'oci_events_rule' for VCN changes should exist", "keyActualValue": "No 'oci_events_rule' found for VCN changes", From cf45a9b90313173ef175c7063152f4e84e7e8f47 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:12 +0100 Subject: [PATCH 641/900] fix(rego): add searchLine to azure_app_service_application_insights_not_configured --- .../query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego index df488173fe3..e916ff5d40b 100644 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego @@ -23,6 +23,7 @@ CxPolicy[result] { "resourceType": resource_type, "resourceName": tf_lib.get_resource_name(app, name), "searchKey": sprintf("%s[%s]", [resource_type, name]), + "searchLine": common_lib.build_search_line(["resource", resource_type, name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'%s.%s' should have 'app_settings' defined", [resource_type, name]), "keyActualValue": sprintf("'%s.%s' is missing 'app_settings'", [resource_type, name]), @@ -44,6 +45,7 @@ CxPolicy[result] { "resourceType": resource_type, "resourceName": tf_lib.get_resource_name(app, name), "searchKey": sprintf("%s[%s].app_settings", [resource_type, name]), + "searchLine": common_lib.build_search_line(["resource", resource_type, name, "app_settings"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'app_settings' should contain 'APPLICATIONINSIGHTS_CONNECTION_STRING'", "keyActualValue": "'app_settings' does not contain Application Insights configuration", From 67fad7a6f8a8149217c9ce76287238f703348e5d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:14 +0100 Subject: [PATCH 642/900] fix(rego): add searchLine to azure_app_service_http_logs_disabled --- .../azure/azure_app_service_http_logs_disabled/query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego index f5914643bc9..b448036ca87 100644 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego @@ -18,6 +18,7 @@ CxPolicy[result] { "resourceType": resource_type, "resourceName": tf_lib.get_resource_name(app, name), "searchKey": sprintf("%s[%s]", [resource_type, name]), + "searchLine": common_lib.build_search_line(["resource", resource_type, name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'%s.%s' should have a 'logs' block defined", [resource_type, name]), "keyActualValue": sprintf("'%s.%s' is missing the 'logs' block", [resource_type, name]), @@ -38,6 +39,7 @@ CxPolicy[result] { "resourceType": resource_type, "resourceName": tf_lib.get_resource_name(app, name), "searchKey": sprintf("%s[%s].logs", [resource_type, name]), + "searchLine": common_lib.build_search_line(["resource", resource_type, name, "logs"], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'%s.%s.logs' should have 'http_logs' configured", [resource_type, name]), "keyActualValue": sprintf("'%s.%s.logs' is missing 'http_logs'", [resource_type, name]), From 7c800c8f2d1ec824dea1a846f553c56120f932c1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:16 +0100 Subject: [PATCH 643/900] fix(rego): add searchLine to azure_backup_vault_cross_region_restore_disabled --- .../azure_backup_vault_cross_region_restore_disabled/query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego index f1b06503a2c..0531bebbaac 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "azurerm_data_protection_backup_vault", "resourceName": tf_lib.get_resource_name(vault, name), "searchKey": sprintf("azurerm_data_protection_backup_vault[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_data_protection_backup_vault", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should have 'cross_region_restore_enabled' set to true", [name]), "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is missing 'cross_region_restore_enabled'", [name]), @@ -33,6 +34,7 @@ CxPolicy[result] { "resourceType": "azurerm_data_protection_backup_vault", "resourceName": tf_lib.get_resource_name(vault, name), "searchKey": sprintf("azurerm_data_protection_backup_vault[%s].cross_region_restore_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_data_protection_backup_vault", name, "cross_region_restore_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'cross_region_restore_enabled' should be set to true", "keyActualValue": "'cross_region_restore_enabled' is set to false", From 7e54d31bc731a24fc6fac298a75b5c5799d7a328 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:17 +0100 Subject: [PATCH 644/900] fix(rego): add searchLine to azure_backup_vault_infrastructure_encryption_disabled --- .../query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego index 4a7c17436f9..8eeb0bfc9b2 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "azurerm_data_protection_backup_vault", "resourceName": tf_lib.get_resource_name(vault, name), "searchKey": sprintf("azurerm_data_protection_backup_vault[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_data_protection_backup_vault", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should have an 'identity' block to support advanced encryption", [name]), "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is missing the 'identity' block", [name]), From 135f573a1a9413265116b7cc9344e01fd8b046f0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:18 +0100 Subject: [PATCH 645/900] fix(rego): add searchLine to azure_bastion_host_missing --- .../terraform/azure/azure_bastion_host_missing/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego b/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego index 7285b599b12..480eae7dc53 100644 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego @@ -18,6 +18,7 @@ CxPolicy[result] { "resourceType": "azurerm_virtual_network", "resourceName": tf_lib.get_resource_name(vnet, name), "searchKey": sprintf("azurerm_virtual_network[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_virtual_network", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("An 'azurerm_bastion_host' resource should be defined to protect Virtual Network '%s'", [name]), "keyActualValue": "No 'azurerm_bastion_host' resource was found in the configuration", From 4fc725087f253bb03de951ff6e692295e66f6a81 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:20 +0100 Subject: [PATCH 646/900] fix(rego): add searchLine to azure_elastic_san_public_access_enabled --- .../azure/azure_elastic_san_public_access_enabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego index 536bb1b9424..0474507405e 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego @@ -16,6 +16,7 @@ CxPolicy[result] { "resourceType": "azurerm_elastic_san_volume_group", "resourceName": tf_lib.get_resource_name(vg, name), "searchKey": sprintf("azurerm_elastic_san_volume_group[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_elastic_san_volume_group", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'azurerm_elastic_san_volume_group.%s' should have a 'network_rule' block to restrict public access", [name]), "keyActualValue": sprintf("'azurerm_elastic_san_volume_group.%s' is missing the 'network_rule' block", [name]), From 95699eb21f7d9f93aa39e16bc591ee0eaf65d0ff Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:21 +0100 Subject: [PATCH 647/900] fix(rego): add searchLine to azure_iot_hub_defender_disabled --- .../terraform/azure/azure_iot_hub_defender_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego index 9a907c6395a..b6b40288bc7 100644 --- a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego @@ -23,6 +23,7 @@ CxPolicy[result] { "resourceType": "azurerm_iothub", "resourceName": tf_lib.get_resource_name(iot_hub, hub_name), "searchKey": sprintf("azurerm_iothub[%s]", [hub_name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_iothub", hub_name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'azurerm_iothub.%s' should be included in 'iothub_ids' of an 'azurerm_iot_security_solution'", [hub_name]), "keyActualValue": sprintf("'azurerm_iothub.%s' is not associated with any 'azurerm_iot_security_solution'", [hub_name]), From b601d390770b4a267b6a5cccf844b3e8498831f7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:23 +0100 Subject: [PATCH 648/900] fix(rego): add searchLine to azure_key_vault_key_rotation_disabled --- .../azure/azure_key_vault_key_rotation_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego index 51c87f675dd..bbcb4f2f952 100644 --- a/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_key_vault_key_rotation_disabled/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "azurerm_key_vault_key", "resourceName": tf_lib.get_resource_name(key, name), "searchKey": sprintf("azurerm_key_vault_key[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_key_vault_key", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'azurerm_key_vault_key.%s' should have a 'rotation_policy' block defined", [name]), "keyActualValue": sprintf("'azurerm_key_vault_key.%s' does not have a 'rotation_policy' block defined", [name]), From 22af3d7d2ea2d86a102d551967ceb6c274dd7101 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:24 +0100 Subject: [PATCH 649/900] fix(rego): add searchLine to azure_managed_lustre_cmk_encryption_disabled --- .../azure_managed_lustre_cmk_encryption_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego index 5564df2db71..9ca2ed4889b 100644 --- a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "azurerm_managed_lustre_file_system", "resourceName": tf_lib.get_resource_name(lustre, name), "searchKey": sprintf("azurerm_managed_lustre_file_system[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_managed_lustre_file_system", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'azurerm_managed_lustre_file_system.%s' should have an 'encryption_key' block defined", [name]), "keyActualValue": sprintf("'azurerm_managed_lustre_file_system.%s' is missing the 'encryption_key' block", [name]), From 1b2ad407280525bd0351564a78731a45ca6fed82 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:25 +0100 Subject: [PATCH 650/900] fix(rego): add searchLine to azure_mysql_audit_log_enabled_manual --- .../azure/azure_mysql_audit_log_enabled_manual/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego index 24fe8627f71..60ea00e6b39 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego @@ -17,6 +17,7 @@ CxPolicy[result] { "resourceType": resource_type, "resourceName": tf_lib.get_resource_name(server, name), "searchKey": sprintf("%s[%s]", [resource_type, name]), + "searchLine": common_lib.build_search_line(["resource", resource_type, name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'audit_log_enabled' should be set to 'ON' for '%s.%s' (Manual Verification)", [resource_type, name]), "keyActualValue": "Logging configuration requires manual verification or check of 'azurerm_mysql_configuration' resources", From 8202eb1966a45536c7227dc924ed17f20a2b925c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:27 +0100 Subject: [PATCH 651/900] fix(rego): add searchLine to azure_mysql_audit_log_events_connection_manual --- .../azure_mysql_audit_log_events_connection_manual/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego index 6534ec55bdc..1f4fd3ea815 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego @@ -17,6 +17,7 @@ CxPolicy[result] { "resourceType": resource_type, "resourceName": tf_lib.get_resource_name(server, name), "searchKey": sprintf("%s[%s]", [resource_type, name]), + "searchLine": common_lib.build_search_line(["resource", resource_type, name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'audit_log_events' should include 'CONNECTION' for '%s.%s' (Manual Verification)", [resource_type, name]), "keyActualValue": "Audit log event configuration requires manual verification or check of 'azurerm_mysql_configuration'", From 21e3add9cdd3cd305fb874815cbf1668bd68e144 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:28 +0100 Subject: [PATCH 652/900] fix(rego): add searchLine to azure_paas_private_endpoint_missing --- .../azure/azure_paas_private_endpoint_missing/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego index 182970378cb..9cae495829c 100644 --- a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/query.rego @@ -44,6 +44,7 @@ CxPolicy[result] { "resourceType": resource_type, "resourceName": tf_lib.get_resource_name(resource_instance, name), "searchKey": sprintf("%s[%s]", [resource_type, name]), + "searchLine": common_lib.build_search_line(["resource", resource_type, name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'%s.%s' should be linked to an 'azurerm_private_endpoint'", [resource_type, name]), "keyActualValue": sprintf("'%s.%s' is not linked to any 'azurerm_private_endpoint' in this file", [resource_type, name]), From d9d6cfcadf77575203925e7f5b2861b44c941916 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:29 +0100 Subject: [PATCH 653/900] fix(rego): add searchLine to azure_production_workload_basic_consumption_sku --- .../azure_production_workload_basic_consumption_sku/query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego index 7cc926ef599..bfdfaa48d71 100644 --- a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/query.rego @@ -16,6 +16,7 @@ CxPolicy[result] { "resourceType": "azurerm_service_plan", "resourceName": tf_lib.get_resource_name(plan, name), "searchKey": sprintf("azurerm_service_plan[%s].sku_name", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_service_plan", name, "sku_name"], []), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("'%s.sku_name' should be Standard (S), Premium (P) or Isolated (I) for production", [name]), "keyActualValue": sprintf("'%s.sku_name' is set to '%s' (Basic/Free/Consumption)", [name, plan.sku_name]), @@ -34,6 +35,7 @@ CxPolicy[result] { "resourceType": "azurerm_api_management", "resourceName": tf_lib.get_resource_name(apim, name), "searchKey": sprintf("azurerm_api_management[%s].sku_name", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_api_management", name, "sku_name"], []), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("'%s.sku_name' should be Standard or Premium for production features", [name]), "keyActualValue": sprintf("'%s.sku_name' is set to '%s'", [name, apim.sku_name]), From 7300f0cb8533c490475f78d8cf9f6939dfd85fe0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:31 +0100 Subject: [PATCH 654/900] fix(rego): add searchLine to azure_recovery_services_vault_cross_region_restore_disabled --- .../query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego index 8ba9c497f22..62945cc7fc4 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "azurerm_recovery_services_vault", "resourceName": tf_lib.get_resource_name(vault, name), "searchKey": sprintf("azurerm_recovery_services_vault[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_recovery_services_vault", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'azurerm_recovery_services_vault.%s' should have 'cross_region_restore_enabled' set to true", [name]), "keyActualValue": sprintf("'azurerm_recovery_services_vault.%s' is missing 'cross_region_restore_enabled'", [name]), @@ -33,6 +34,7 @@ CxPolicy[result] { "resourceType": "azurerm_recovery_services_vault", "resourceName": tf_lib.get_resource_name(vault, name), "searchKey": sprintf("azurerm_recovery_services_vault[%s].cross_region_restore_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_recovery_services_vault", name, "cross_region_restore_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'cross_region_restore_enabled' should be set to true", "keyActualValue": "'cross_region_restore_enabled' is set to false", From 2e2b839ccf7e72bf59c30afbd10033a6941093a7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:32 +0100 Subject: [PATCH 655/900] fix(rego): add searchLine to azure_recovery_services_vault_infrastructure_encryption_disabled --- .../query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego index 81589034907..acb87f881d1 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_infrastructure_encryption_disabled/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "azurerm_recovery_services_vault", "resourceName": tf_lib.get_resource_name(vault, name), "searchKey": sprintf("azurerm_recovery_services_vault[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_recovery_services_vault", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'azurerm_recovery_services_vault.%s' should have an 'encryption' block defined", [name]), "keyActualValue": sprintf("'azurerm_recovery_services_vault.%s' is missing the 'encryption' block", [name]), @@ -34,6 +35,7 @@ CxPolicy[result] { "resourceType": "azurerm_recovery_services_vault", "resourceName": tf_lib.get_resource_name(vault, name), "searchKey": sprintf("azurerm_recovery_services_vault[%s].encryption.infrastructure_encryption_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_recovery_services_vault", name, "encryption", "infrastructure_encryption_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "encryption.infrastructure_encryption_enabled should be set to true", "keyActualValue": sprintf("encryption.infrastructure_encryption_enabled is set to %v", [object.get(vault.encryption, "infrastructure_encryption_enabled", false)]), From d3c6d80fe7985e152e190bb93858e3df104d22c2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:34 +0100 Subject: [PATCH 656/900] fix(rego): add searchLine to azure_storage_account_geo_redundancy_disabled --- .../azure_storage_account_geo_redundancy_disabled/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego index 5bcd3ffbdcf..fb754480e3f 100644 --- a/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_geo_redundancy_disabled/query.rego @@ -19,6 +19,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_account", "resourceName": tf_lib.get_resource_name(sa, name), "searchKey": sprintf("azurerm_storage_account[%s].account_replication_type", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", name, "account_replication_type"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'account_replication_type' should be 'GRS', 'RAGRS', 'GZRS', or 'RAGZRS'", "keyActualValue": sprintf("'account_replication_type' is set to '%s'", [current_type]), From 652b12752b69d3975f0f3ddaf7a95df779416e3d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:35 +0100 Subject: [PATCH 657/900] fix(rego): add searchLine to azure_storage_account_infrastructure_encryption_disabled --- .../query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego index 08c46aa595e..4aba3fefbe3 100644 --- a/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_infrastructure_encryption_disabled/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_account", "resourceName": tf_lib.get_resource_name(sa, name), "searchKey": sprintf("azurerm_storage_account[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have 'infrastructure_encryption_enabled' set to true", [name]), "keyActualValue": sprintf("'azurerm_storage_account.%s' is missing 'infrastructure_encryption_enabled'", [name]), @@ -33,6 +34,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_account", "resourceName": tf_lib.get_resource_name(sa, name), "searchKey": sprintf("azurerm_storage_account[%s].infrastructure_encryption_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", name, "infrastructure_encryption_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'infrastructure_encryption_enabled' should be set to true", "keyActualValue": "'infrastructure_encryption_enabled' is set to false", From aec2ee67e1f229555d048ebc4bf0f2176af8d143 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:36 +0100 Subject: [PATCH 658/900] fix(rego): add searchLine to azure_storage_account_read_only_lock_missing --- .../azure_storage_account_read_only_lock_missing/query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego index 2013114368b..cd71dfae1d5 100644 --- a/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_read_only_lock_missing/query.rego @@ -34,6 +34,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_account", "resourceName": tf_lib.get_resource_name(sa, sa_name), "searchKey": sprintf("azurerm_storage_account[%s]", [sa_name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", sa_name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have a 'ReadOnly' lock associated", [sa_name]), "keyActualValue": sprintf("'azurerm_storage_account.%s' has no locks associated", [sa_name]), @@ -58,6 +59,7 @@ CxPolicy[result] { "resourceType": "azurerm_management_lock", "resourceName": tf_lib.get_resource_name(lock, lock_name), "searchKey": sprintf("azurerm_management_lock[%s].lock_level", [lock_name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_management_lock", lock_name, "lock_level"], []), "issueType": "IncorrectValue", "keyExpectedValue": sprintf("'azurerm_management_lock.%s.lock_level' should be 'ReadOnly'", [lock_name]), "keyActualValue": sprintf("'azurerm_management_lock.%s.lock_level' is '%s'", [lock_name, lock.lock_level]), From 2c446971464ff03ff0574e50b51eb1f5d635566b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:37 +0100 Subject: [PATCH 659/900] fix(rego): add searchLine to azure_storage_account_versioning_disabled --- .../azure/azure_storage_account_versioning_disabled/query.rego | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego index fd1046ae58f..ba4c7943869 100644 --- a/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_account_versioning_disabled/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_account", "resourceName": tf_lib.get_resource_name(sa, name), "searchKey": sprintf("azurerm_storage_account[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have 'blob_properties' defined", [name]), "keyActualValue": sprintf("'azurerm_storage_account.%s' is missing 'blob_properties'", [name]), @@ -35,6 +36,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_account", "resourceName": tf_lib.get_resource_name(sa, name), "searchKey": sprintf("azurerm_storage_account[%s].blob_properties", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", name, "blob_properties"], []), "issueType": "MissingAttribute", "keyExpectedValue": "blob_properties.versioning_enabled should be defined and set to true", "keyActualValue": "blob_properties.versioning_enabled is missing", @@ -53,6 +55,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_account", "resourceName": tf_lib.get_resource_name(sa, name), "searchKey": sprintf("azurerm_storage_account[%s].blob_properties.versioning_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", name, "blob_properties", "versioning_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "blob_properties.versioning_enabled should be set to true", "keyActualValue": "blob_properties.versioning_enabled is set to false", From 44c9e0e611d5ae144c9a8cdddd2ab0c911c7cd99 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:39 +0100 Subject: [PATCH 660/900] fix(rego): add searchLine to azure_storage_blob_logging_disabled --- .../azure/azure_storage_blob_logging_disabled/query.rego | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego index 7c068a0df48..06f2b1dfa55 100644 --- a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/query.rego @@ -27,6 +27,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_account", "resourceName": tf_lib.get_resource_name(sa, name), "searchKey": sprintf("azurerm_storage_account[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have an 'azurerm_monitor_diagnostic_setting' for its blob service", [name]), "keyActualValue": sprintf("'azurerm_storage_account.%s' does not have diagnostic logging enabled for blobs", [name]), @@ -51,6 +52,7 @@ CxPolicy[result] { "resourceType": "azurerm_monitor_diagnostic_setting", "resourceName": tf_lib.get_resource_name(diag, diag_name), "searchKey": sprintf("azurerm_monitor_diagnostic_setting[%s]", [diag_name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_monitor_diagnostic_setting", diag_name], []), "issueType": "MissingAttribute", "keyExpectedValue": "Diagnostic Setting should have 'enabled_log' blocks defined", "keyActualValue": "Diagnostic Setting has no 'enabled_log' blocks", @@ -78,6 +80,7 @@ CxPolicy[result] { "resourceType": "azurerm_monitor_diagnostic_setting", "resourceName": tf_lib.get_resource_name(diag, diag_name), "searchKey": sprintf("azurerm_monitor_diagnostic_setting[%s].enabled_log", [diag_name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_monitor_diagnostic_setting", diag_name, "enabled_log"], []), "issueType": "IncorrectValue", "keyExpectedValue": "All required log categories (StorageRead, StorageWrite, StorageDelete) should be present", "keyActualValue": "One or more required log categories are missing in the 'enabled_log' configuration", From fef47fdbe3f34211fae6507a97910ebde4256ab9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:40 +0100 Subject: [PATCH 661/900] fix(rego): add searchLine to azure_storage_container_immutability_not_locked --- .../azure_storage_container_immutability_not_locked/query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego index f041b700963..cd85af72e4a 100644 --- a/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego +++ b/assets/queries/terraform/azure/azure_storage_container_immutability_not_locked/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_container_immutability_policy", "resourceName": tf_lib.get_resource_name(policy, name), "searchKey": sprintf("azurerm_storage_container_immutability_policy[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_container_immutability_policy", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'azurerm_storage_container_immutability_policy.%s' should have 'locked' set to true", [name]), "keyActualValue": sprintf("'azurerm_storage_container_immutability_policy.%s' is missing 'locked' attribute (default is false)", [name]), @@ -33,6 +34,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_container_immutability_policy", "resourceName": tf_lib.get_resource_name(policy, name), "searchKey": sprintf("azurerm_storage_container_immutability_policy[%s].locked", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_container_immutability_policy", name, "locked"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'locked' should be set to true", "keyActualValue": "'locked' is set to false", From 4a11cedd08a7514b410f932a22b806ac8d5bb71a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:41 +0100 Subject: [PATCH 662/900] fix(rego): add searchLine to azure_storage_queue_logging_disabled --- .../azure/azure_storage_queue_logging_disabled/query.rego | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego index 212e701545f..0fa23b2c725 100644 --- a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/query.rego @@ -22,6 +22,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_account", "resourceName": tf_lib.get_resource_name(sa, name), "searchKey": sprintf("azurerm_storage_account[%s].queue_properties", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", name, "queue_properties"], []), "issueType": "MissingAttribute", "keyExpectedValue": "queue_properties.logging should be defined with read, write, and delete enabled", "keyActualValue": "queue_properties.logging is missing", @@ -41,6 +42,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_account", "resourceName": tf_lib.get_resource_name(sa, name), "searchKey": sprintf("azurerm_storage_account[%s].queue_properties.logging", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", name, "queue_properties", "logging"], []), "issueType": "IncorrectValue", "keyExpectedValue": "logging should have read, write, and delete set to true", "keyActualValue": "logging has one or more required actions (read, write, delete) disabled", @@ -59,6 +61,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_account_queue_properties", "resourceName": tf_lib.get_resource_name(props, name), "searchKey": sprintf("azurerm_storage_account_queue_properties[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account_queue_properties", name], []), "issueType": "MissingAttribute", "keyExpectedValue": "logging block should be defined in queue properties", "keyActualValue": "logging block is missing", @@ -78,6 +81,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_account_queue_properties", "resourceName": tf_lib.get_resource_name(props, name), "searchKey": sprintf("azurerm_storage_account_queue_properties[%s].logging", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account_queue_properties", name, "logging"], []), "issueType": "IncorrectValue", "keyExpectedValue": "logging should have read, write, and delete set to true", "keyActualValue": "logging is missing one or more required actions", From 2417d49081d9f28a998369ded5f82fb638c9c58b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:43 +0100 Subject: [PATCH 663/900] fix(rego): add searchLine to azure_storage_table_logging_disabled --- .../azure/azure_storage_table_logging_disabled/query.rego | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego index 3b5defba49b..9c3a9b51ff1 100644 --- a/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_storage_table_logging_disabled/query.rego @@ -27,6 +27,7 @@ CxPolicy[result] { "resourceType": "azurerm_storage_account", "resourceName": tf_lib.get_resource_name(sa, name), "searchKey": sprintf("azurerm_storage_account[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_storage_account", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'azurerm_storage_account.%s' should have an 'azurerm_monitor_diagnostic_setting' for its table service", [name]), "keyActualValue": sprintf("'azurerm_storage_account.%s' does not have diagnostic logging enabled for tables", [name]), @@ -51,6 +52,7 @@ CxPolicy[result] { "resourceType": "azurerm_monitor_diagnostic_setting", "resourceName": tf_lib.get_resource_name(diag, diag_name), "searchKey": sprintf("azurerm_monitor_diagnostic_setting[%s]", [diag_name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_monitor_diagnostic_setting", diag_name], []), "issueType": "MissingAttribute", "keyExpectedValue": "Diagnostic Setting should have 'enabled_log' blocks defined", "keyActualValue": "Diagnostic Setting has no 'enabled_log' blocks", @@ -78,6 +80,7 @@ CxPolicy[result] { "resourceType": "azurerm_monitor_diagnostic_setting", "resourceName": tf_lib.get_resource_name(diag, diag_name), "searchKey": sprintf("azurerm_monitor_diagnostic_setting[%s].enabled_log", [diag_name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_monitor_diagnostic_setting", diag_name, "enabled_log"], []), "issueType": "IncorrectValue", "keyExpectedValue": "All required log categories (StorageRead, StorageWrite, StorageDelete) should be present", "keyActualValue": "One or more required log categories are missing in the 'enabled_log' configuration for Table service", From 0f8a25e4876b66b54a5ed25e56e6d7fe5c35fd1e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:44 +0100 Subject: [PATCH 664/900] fix(rego): add searchLine to gcp_access_approval_disabled --- .../terraform/gcp/gcp_access_approval_disabled/query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego b/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego index 5eb474be768..53b3886d424 100644 --- a/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/query.rego @@ -20,6 +20,7 @@ CxPolicy[result] { "resourceType": "google_project", "resourceName": tf_lib.get_resource_name(project, name), "searchKey": sprintf("google_project[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_project", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'google_project.%s' should have 'google_access_approval_project_settings' associated", [name]), "keyActualValue": sprintf("'google_project.%s' does not have Access Approval configured", [name]), @@ -38,6 +39,7 @@ CxPolicy[result] { "resourceType": "google_access_approval_project_settings", "resourceName": tf_lib.get_resource_name(settings, name), "searchKey": sprintf("google_access_approval_project_settings[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_access_approval_project_settings", name], []), "issueType": "MissingAttribute", "keyExpectedValue": "Must have at least one 'enrolled_services' block defined", "keyActualValue": "'enrolled_services' is missing", From bbc5d70158ea3673f91a067d8ccf53d2b80c19d8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:45 +0100 Subject: [PATCH 665/900] fix(rego): add searchLine to gcp_api_key_api_targets_missing --- .../terraform/gcp/gcp_api_key_api_targets_missing/query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego index b80f1d8daf6..ce3d7101e2c 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "google_apikeys_key", "resourceName": tf_lib.get_resource_name(key, name), "searchKey": sprintf("google_apikeys_key[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_apikeys_key", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'google_apikeys_key.%s' should have 'restrictions.api_targets' defined", [name]), "keyActualValue": sprintf("'google_apikeys_key.%s' is missing the 'restrictions' block", [name]), @@ -34,6 +35,7 @@ CxPolicy[result] { "resourceType": "google_apikeys_key", "resourceName": tf_lib.get_resource_name(key, name), "searchKey": sprintf("google_apikeys_key[%s].restrictions", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_apikeys_key", name, "restrictions"], []), "issueType": "MissingAttribute", "keyExpectedValue": "restrictions.api_targets should be defined", "keyActualValue": "restrictions.api_targets is missing", From e81ac64e80a0d48114dbb5a1c8cbe68aedf6db11 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:47 +0100 Subject: [PATCH 666/900] fix(rego): add searchLine to gcp_api_key_restrictions_manual --- .../terraform/gcp/gcp_api_key_restrictions_manual/query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego index 5c9be6360ba..812040427f7 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "google_apikeys_key", "resourceName": tf_lib.get_resource_name(key, name), "searchKey": sprintf("google_apikeys_key[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_apikeys_key", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'google_apikeys_key.%s' should have a 'restrictions' block defined", [name]), "keyActualValue": sprintf("'google_apikeys_key.%s' is missing the 'restrictions' block", [name]), @@ -33,6 +34,7 @@ CxPolicy[result] { "resourceType": "google_apikeys_key", "resourceName": tf_lib.get_resource_name(key, name), "searchKey": sprintf("google_apikeys_key[%s].restrictions", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_apikeys_key", name, "restrictions"], []), "issueType": "IncorrectValue", "keyExpectedValue": "Restrictions should be verified against allowed IPs/Referrers", "keyActualValue": "Restrictions are present. Manual verification required.", From 768e859b1a33a45c8fb5974a7dce82c837ed4ef3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:48 +0100 Subject: [PATCH 667/900] fix(rego): add searchLine to gcp_app_engine_https_enforcement_manual --- .../gcp/gcp_app_engine_https_enforcement_manual/query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego index cd06bace053..9aadc258e53 100644 --- a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/query.rego @@ -24,6 +24,7 @@ CxPolicy[result] { "resourceType": "google_app_engine_standard_app_version", "resourceName": tf_lib.get_resource_name(app, name), "searchKey": sprintf("google_app_engine_standard_app_version[%s].handlers", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_app_engine_standard_app_version", name, "handlers"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'handlers.security_level' should be set to 'SECURE_ALWAYS'", "keyActualValue": sprintf("'handlers.security_level' is set to '%s'", [sec_level]), @@ -42,6 +43,7 @@ CxPolicy[result] { "resourceType": "google_app_engine_standard_app_version", "resourceName": tf_lib.get_resource_name(app, name), "searchKey": sprintf("google_app_engine_standard_app_version[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_app_engine_standard_app_version", name], []), "issueType": "MissingAttribute", "keyExpectedValue": "If handlers are not defined in Terraform, verify 'app.yaml' contains 'secure: always'", "keyActualValue": "Terraform does not define handlers. Manual verification of 'app.yaml' required.", From 8b1c511997f6e0944e0c42742757a40dd8f68be3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:49 +0100 Subject: [PATCH 668/900] fix(rego): add searchLine to gcp_compute_logging_service_disabled --- .../gcp/gcp_compute_logging_service_disabled/query.rego | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego index ea451702172..b3c0a719244 100644 --- a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "google_compute_instance", "resourceName": tf_lib.get_resource_name(instance, name), "searchKey": sprintf("google_compute_instance[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_compute_instance", name], []), "issueType": "MissingAttribute", "keyExpectedValue": "'metadata' block should be defined and contain 'google-logging-enabled'", "keyActualValue": "'metadata' block is missing", @@ -34,6 +35,7 @@ CxPolicy[result] { "resourceType": "google_compute_instance", "resourceName": tf_lib.get_resource_name(instance, name), "searchKey": sprintf("google_compute_instance[%s].metadata", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_compute_instance", name, "metadata"], []), "issueType": "MissingAttribute", "keyExpectedValue": "'google-logging-enabled' should be defined within metadata", "keyActualValue": "'google-logging-enabled' is missing in metadata", @@ -53,6 +55,7 @@ CxPolicy[result] { "resourceType": "google_compute_instance", "resourceName": tf_lib.get_resource_name(instance, name), "searchKey": sprintf("google_compute_instance[%s].metadata.google-logging-enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_compute_instance", name, "metadata", "google-logging-enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'google-logging-enabled' should be set to 'true'", "keyActualValue": "'google-logging-enabled' is set to 'false'", From f2d36a765e53369da23fde3a9129824d28d6e68b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:51 +0100 Subject: [PATCH 669/900] fix(rego): add searchLine to gcp_gke_default_service_account_used --- .../gcp/gcp_gke_default_service_account_used/query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego index 4641ae0da74..d0cc02fabf6 100644 --- a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "google_container_cluster", "resourceName": tf_lib.get_resource_name(resource, name), "searchKey": sprintf("google_container_cluster[%s].node_config", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_container_cluster", name, "node_config"], []), "issueType": "MissingAttribute", "keyExpectedValue": "'service_account' should be explicitly defined in node_config", "keyActualValue": "'service_account' is missing, defaulting to the Compute Engine default service account", @@ -33,6 +34,7 @@ CxPolicy[result] { "resourceType": "google_container_node_pool", "resourceName": tf_lib.get_resource_name(resource, name), "searchKey": sprintf("google_container_node_pool[%s].node_config", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_container_node_pool", name, "node_config"], []), "issueType": "MissingAttribute", "keyExpectedValue": "'service_account' should be explicitly defined in node_config", "keyActualValue": "'service_account' is missing, defaulting to the Compute Engine default service account", From 1db7827f295c52bba95b9bd4ffee6ba305866846 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:52 +0100 Subject: [PATCH 670/900] fix(rego): add searchLine to gcp_gke_metadata_server_disabled --- .../terraform/gcp/gcp_gke_metadata_server_disabled/query.rego | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego index c44fa685cce..abb38ab0db9 100644 --- a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "google_container_cluster", "resourceName": tf_lib.get_resource_name(resource, name), "searchKey": sprintf("google_container_cluster[%s].node_config", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_container_cluster", name, "node_config"], []), "issueType": "MissingAttribute", "keyExpectedValue": "'workload_metadata_config' should be defined with mode 'GKE_METADATA'", "keyActualValue": "'workload_metadata_config' is missing", @@ -33,6 +34,7 @@ CxPolicy[result] { "resourceType": "google_container_node_pool", "resourceName": tf_lib.get_resource_name(resource, name), "searchKey": sprintf("google_container_node_pool[%s].node_config", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_container_node_pool", name, "node_config"], []), "issueType": "MissingAttribute", "keyExpectedValue": "'workload_metadata_config' should be defined with mode 'GKE_METADATA'", "keyActualValue": "'workload_metadata_config' is missing", @@ -51,6 +53,7 @@ CxPolicy[result] { "resourceType": "google_container_cluster", "resourceName": tf_lib.get_resource_name(resource, name), "searchKey": sprintf("google_container_cluster[%s].node_config.workload_metadata_config.mode", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_container_cluster", name, "node_config", "workload_metadata_config", "mode"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'mode' should be set to 'GKE_METADATA'", "keyActualValue": sprintf("'mode' is set to '%s'", [resource.node_config.workload_metadata_config.mode]), @@ -69,6 +72,7 @@ CxPolicy[result] { "resourceType": "google_container_node_pool", "resourceName": tf_lib.get_resource_name(resource, name), "searchKey": sprintf("google_container_node_pool[%s].node_config.workload_metadata_config.mode", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_container_node_pool", name, "node_config", "workload_metadata_config", "mode"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'mode' should be set to 'GKE_METADATA'", "keyActualValue": sprintf("'mode' is set to '%s'", [resource.node_config.workload_metadata_config.mode]), From a9472104cd67fe8bbd35e53b2a873b185405424d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:53 +0100 Subject: [PATCH 671/900] fix(rego): add searchLine to gcp_gke_sandbox_disabled --- .../queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego index 9bedcb2f493..b1b287951b8 100644 --- a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "google_container_cluster", "resourceName": tf_lib.get_resource_name(resource, name), "searchKey": sprintf("google_container_cluster[%s].node_config", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_container_cluster", name, "node_config"], []), "issueType": "MissingAttribute", "keyExpectedValue": "'sandbox_config' should be defined with sandbox_type 'gvisor'", "keyActualValue": "'sandbox_config' is missing", @@ -33,6 +34,7 @@ CxPolicy[result] { "resourceType": "google_container_node_pool", "resourceName": tf_lib.get_resource_name(resource, name), "searchKey": sprintf("google_container_node_pool[%s].node_config", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_container_node_pool", name, "node_config"], []), "issueType": "MissingAttribute", "keyExpectedValue": "'sandbox_config' should be defined with sandbox_type 'gvisor'", "keyActualValue": "'sandbox_config' is missing", @@ -51,6 +53,7 @@ CxPolicy[result] { "resourceType": "google_container_cluster", "resourceName": tf_lib.get_resource_name(resource, name), "searchKey": sprintf("google_container_cluster[%s].node_config.sandbox_config.sandbox_type", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_container_cluster", name, "node_config", "sandbox_config", "sandbox_type"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'sandbox_type' should be 'gvisor'", "keyActualValue": sprintf("'sandbox_type' is set to '%s'", [resource.node_config.sandbox_config.sandbox_type]), @@ -69,6 +72,7 @@ CxPolicy[result] { "resourceType": "google_container_node_pool", "resourceName": tf_lib.get_resource_name(resource, name), "searchKey": sprintf("google_container_node_pool[%s].node_config.sandbox_config.sandbox_type", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_container_node_pool", name, "node_config", "sandbox_config", "sandbox_type"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'sandbox_type' should be 'gvisor'", "keyActualValue": sprintf("'sandbox_type' is set to '%s'", [resource.node_config.sandbox_config.sandbox_type]), From 12ca5744584b59979b003404b6a952aeafe8b532 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:54 +0100 Subject: [PATCH 672/900] fix(rego): add searchLine to gcp_gke_secrets_encryption_cmek_disabled --- .../gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego index ec17cc8d57a..4178e7d99c2 100644 --- a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "google_container_cluster", "resourceName": tf_lib.get_resource_name(cluster, name), "searchKey": sprintf("google_container_cluster[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_container_cluster", name], []), "issueType": "MissingAttribute", "keyExpectedValue": "'database_encryption' block should be defined", "keyActualValue": "'database_encryption' block is missing", @@ -33,6 +34,7 @@ CxPolicy[result] { "resourceType": "google_container_cluster", "resourceName": tf_lib.get_resource_name(cluster, name), "searchKey": sprintf("google_container_cluster[%s].database_encryption.state", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_container_cluster", name, "database_encryption", "state"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'state' should be set to 'ENCRYPTED'", "keyActualValue": sprintf("'state' is set to '%s'", [cluster.database_encryption.state]), @@ -54,6 +56,7 @@ CxPolicy[result] { "resourceType": "google_container_cluster", "resourceName": tf_lib.get_resource_name(cluster, name), "searchKey": sprintf("google_container_cluster[%s].database_encryption.key_name", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_container_cluster", name, "database_encryption", "key_name"], []), "issueType": "MissingAttribute", "keyExpectedValue": "'key_name' should be defined with a valid KMS key ID", "keyActualValue": "'key_name' is missing or empty", From 0fcbd1a41da7eebf078e16568ab45ed7574a8444 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:56 +0100 Subject: [PATCH 673/900] fix(rego): add searchLine to gcp_http_load_balancer_logging_disabled --- .../gcp/gcp_http_load_balancer_logging_disabled/query.rego | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego index fb8c4c6924b..ce9034bfa68 100644 --- a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "google_compute_backend_service", "resourceName": tf_lib.get_resource_name(bs, name), "searchKey": sprintf("google_compute_backend_service[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_compute_backend_service", name], []), "issueType": "MissingAttribute", "keyExpectedValue": "log_config should be defined with enable set to true", "keyActualValue": "log_config is missing", @@ -33,6 +34,7 @@ CxPolicy[result] { "resourceType": "google_compute_backend_service", "resourceName": tf_lib.get_resource_name(bs, name), "searchKey": sprintf("google_compute_backend_service[%s].log_config.enable", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_compute_backend_service", name, "log_config", "enable"], []), "issueType": "IncorrectValue", "keyExpectedValue": "log_config.enable should be set to true", "keyActualValue": "log_config.enable is set to false", From 2370e20d0fc9c1ed50a610e1b8afdd921ffed0ee Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:57 +0100 Subject: [PATCH 674/900] fix(rego): add searchLine to gcp_iap_backend_service_disabled --- .../terraform/gcp/gcp_iap_backend_service_disabled/query.rego | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego index 37a83794a37..0de21c99587 100644 --- a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego @@ -15,6 +15,7 @@ CxPolicy[result] { "resourceType": "google_compute_backend_service", "resourceName": tf_lib.get_resource_name(bs, name), "searchKey": sprintf("google_compute_backend_service[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_compute_backend_service", name], []), "issueType": "MissingAttribute", "keyExpectedValue": sprintf("'google_compute_backend_service.%s' should have an 'iap' block defined", [name]), "keyActualValue": sprintf("'google_compute_backend_service.%s' is missing the 'iap' block", [name]), @@ -34,6 +35,7 @@ CxPolicy[result] { "resourceType": "google_compute_backend_service", "resourceName": tf_lib.get_resource_name(bs, name), "searchKey": sprintf("google_compute_backend_service[%s].iap", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_compute_backend_service", name, "iap"], []), "issueType": "MissingAttribute", "keyExpectedValue": "'oauth2_client_id' should be defined within the 'iap' block", "keyActualValue": "'oauth2_client_id' is missing", @@ -53,6 +55,7 @@ CxPolicy[result] { "resourceType": "google_compute_backend_service", "resourceName": tf_lib.get_resource_name(bs, name), "searchKey": sprintf("google_compute_backend_service[%s].iap", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_compute_backend_service", name, "iap"], []), "issueType": "MissingAttribute", "keyExpectedValue": "'oauth2_client_secret' should be defined within the 'iap' block", "keyActualValue": "'oauth2_client_secret' is missing", From 4b48a9db303c2bc2bd8abffad1788713bfb375ff Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:31:58 +0100 Subject: [PATCH 675/900] fix(rego): add searchLine to gcp_sql_postgresql_log_error_verbosity_verbose --- .../gcp_sql_postgresql_log_error_verbosity_verbose/query.rego | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego index 710d3ea7c44..bbae6e1880e 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_error_verbosity_verbose/query.rego @@ -23,6 +23,7 @@ CxPolicy[result] { "resourceType": "google_sql_database_instance", "resourceName": tf_lib.get_resource_name(resource, name), "searchKey": sprintf("google_sql_database_instance[%s].settings.database_flags", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_sql_database_instance", name, "settings", "database_flags"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'log_error_verbosity' should be set to 'default' or 'terse'", "keyActualValue": sprintf("'log_error_verbosity' is set to '%s'", [flag.value]), From d40ee7cd86798844726290692f505d81fe564345 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:32:10 +0100 Subject: [PATCH 676/900] fix(rego): add searchLine to oci_compute_secure_boot_disabled --- .../terraform/oci/oci_compute_secure_boot_disabled/query.rego | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego index 3095e105efc..ae3029b847c 100644 --- a/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego +++ b/assets/queries/terraform/oci/oci_compute_secure_boot_disabled/query.rego @@ -11,6 +11,7 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_core_instance.%s", [instance_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_core_instance", instance_name], []), "issueType": "MissingAttribute", "keyExpectedValue": "'platform_config' block should be defined with 'is_secure_boot_enabled' set to true", "keyActualValue": "'platform_config' block is missing", @@ -27,6 +28,7 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_core_instance.%s.platform_config", [instance_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_core_instance", instance_name, "platform_config"], []), "issueType": "MissingAttribute", "keyExpectedValue": "'is_secure_boot_enabled' should be present inside 'platform_config' and set to 'true'", "keyActualValue": "'is_secure_boot_enabled' is missing inside 'platform_config'", @@ -42,6 +44,7 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_core_instance.%s.platform_config.is_secure_boot_enabled", [instance_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_core_instance", instance_name, "platform_config", "is_secure_boot_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'is_secure_boot_enabled' attribute should be 'true'", "keyActualValue": "'is_secure_boot_enabled' attribute is 'false'", From 8d2a5eade1d9978aa1a1d590c324023519340b59 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:09 +0100 Subject: [PATCH 677/900] fix(rego): add searchLine to gcp_sql_postgresql_log_statement_improperly_set --- .../query.rego | 110 +++++++++--------- 1 file changed, 56 insertions(+), 54 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego index f002dde382a..12cf6d49f05 100644 --- a/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego +++ b/assets/queries/terraform/gcp/gcp_sql_postgresql_log_statement_improperly_set/query.rego @@ -1,56 +1,58 @@ -package Cx - +package Cx + import data.generic.common as common_lib -import data.generic.terraform as tf_lib - -ensure_array(x) = x { is_array(x) } -ensure_array(x) = [x] { is_object(x) } - -has_log_statement(flags_list) { - flag := flags_list[_] - flag.name == "log_statement" -} - -# RULE 1: The 'log_statement' flag is not defined (Missing). -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_sql_database_instance[name] - - contains(resource.database_version, "POSTGRES") - - flags_list := ensure_array(resource.settings.database_flags) - not has_log_statement(flags_list) - - result := { - "documentId": doc.id, - "resourceType": "google_sql_database_instance", - "resourceName": tf_lib.get_resource_name(resource, name), - "searchKey": sprintf("google_sql_database_instance[%s].settings.database_flags", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'database_flags' should include 'log_statement' set to 'ddl', 'mod', or 'all'", - "keyActualValue": "'log_statement' flag is missing (defaults to 'none')", - } -} - -# RULE 2: The 'log_statement' flag exists but is set to 'none'. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.google_sql_database_instance[name] - - contains(resource.database_version, "POSTGRES") - - flags_list := ensure_array(resource.settings.database_flags) - flag := flags_list[_] - flag.name == "log_statement" - lower(flag.value) == "none" - - result := { - "documentId": doc.id, - "resourceType": "google_sql_database_instance", - "resourceName": tf_lib.get_resource_name(resource, name), - "searchKey": sprintf("google_sql_database_instance[%s].settings.database_flags", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'log_statement' should be set to 'ddl', 'mod', or 'all'", - "keyActualValue": "'log_statement' is set to 'none'", - } +import data.generic.terraform as tf_lib + +ensure_array(x) = x { is_array(x) } +ensure_array(x) = [x] { is_object(x) } + +has_log_statement(flags_list) { + flag := flags_list[_] + flag.name == "log_statement" +} + +# RULE 1: The 'log_statement' flag is not defined (Missing). +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_sql_database_instance[name] + + contains(resource.database_version, "POSTGRES") + + flags_list := ensure_array(resource.settings.database_flags) + not has_log_statement(flags_list) + + result := { + "documentId": doc.id, + "resourceType": "google_sql_database_instance", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_sql_database_instance[%s].settings.database_flags", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_sql_database_instance", name, "settings", "database_flags"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'database_flags' should include 'log_statement' set to 'ddl', 'mod', or 'all'", + "keyActualValue": "'log_statement' flag is missing (defaults to 'none')", + } +} + +# RULE 2: The 'log_statement' flag exists but is set to 'none'. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.google_sql_database_instance[name] + + contains(resource.database_version, "POSTGRES") + + flags_list := ensure_array(resource.settings.database_flags) + flag := flags_list[_] + flag.name == "log_statement" + lower(flag.value) == "none" + + result := { + "documentId": doc.id, + "resourceType": "google_sql_database_instance", + "resourceName": tf_lib.get_resource_name(resource, name), + "searchKey": sprintf("google_sql_database_instance[%s].settings.database_flags", [name]), + "searchLine": common_lib.build_search_line(["resource", "google_sql_database_instance", name, "settings", "database_flags"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'log_statement' should be set to 'ddl', 'mod', or 'all'", + "keyActualValue": "'log_statement' is set to 'none'", + } } \ No newline at end of file From 85ebf3ffbb973a4936bf8a1f37320c7c6cc35d3e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:11 +0100 Subject: [PATCH 678/900] fix(rego): add searchLine to ibm_certificate_manager_auto_renew_disabled --- .../query.rego | 68 ++++++++++--------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/query.rego b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/query.rego index 9a54f0dae44..9999c9731df 100644 --- a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/query.rego @@ -1,33 +1,37 @@ -package Cx - -# REGLA 1: El atributo 'auto_renew_enabled' está ausente en el certificado. -CxPolicy[result] { - doc := input.document[i] - certificate := doc.resource.ibm_cm_certificate[cert_name] - - object.get(certificate, "auto_renew_enabled", null) == null - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_cm_certificate.%s", [cert_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'auto_renew_enabled' should be present and set to 'true'", - "keyActualValue": "'auto_renew_enabled' is missing and defaults to 'false'", - } -} - -# REGLA 2: El atributo 'auto_renew_enabled' está explícitamente configurado como 'false'. -CxPolicy[result] { - doc := input.document[i] - certificate := doc.resource.ibm_cm_certificate[cert_name] - - certificate.auto_renew_enabled == false - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_cm_certificate.%s.auto_renew_enabled", [cert_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'auto_renew_enabled' attribute should be 'true'", - "keyActualValue": "'auto_renew_enabled' attribute is 'false'", - } +package Cx + +import data.generic.common as common_lib + +# REGLA 1: El atributo 'auto_renew_enabled' está ausente en el certificado. +CxPolicy[result] { + doc := input.document[i] + certificate := doc.resource.ibm_cm_certificate[cert_name] + + object.get(certificate, "auto_renew_enabled", null) == null + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_cm_certificate.%s", [cert_name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_cm_certificate", cert_name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'auto_renew_enabled' should be present and set to 'true'", + "keyActualValue": "'auto_renew_enabled' is missing and defaults to 'false'", + } +} + +# REGLA 2: El atributo 'auto_renew_enabled' está explícitamente configurado como 'false'. +CxPolicy[result] { + doc := input.document[i] + certificate := doc.resource.ibm_cm_certificate[cert_name] + + certificate.auto_renew_enabled == false + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_cm_certificate.%s.auto_renew_enabled", [cert_name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_cm_certificate", cert_name, "auto_renew_enabled"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'auto_renew_enabled' attribute should be 'true'", + "keyActualValue": "'auto_renew_enabled' attribute is 'false'", + } } \ No newline at end of file From c8d4e32ef4cb7c1273a2c12333c139f232de3f15 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:13 +0100 Subject: [PATCH 679/900] fix(rego): add searchLine to ibm_cis_dns_not_proxied_manual --- .../ibm_cis_dns_not_proxied_manual/query.rego | 68 ++++++++++--------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/query.rego b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/query.rego index 86d3a509490..1932c75cf04 100644 --- a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/query.rego +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/query.rego @@ -1,33 +1,37 @@ -package Cx - -# CASO 1: El atributo 'proxied' está explícitamente en false. -CxPolicy[result] { - doc := input.document[i] - record := doc.resource.ibm_cis_dns_record[name] - - record.proxied == false - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_cis_dns_record.%s.proxied", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'proxied' should be set to 'true' to enable DDoS protection", - "keyActualValue": "'proxied' is set to 'false'", - } -} - -# CASO 2: El atributo 'proxied' falta (por defecto es false). -CxPolicy[result] { - doc := input.document[i] - record := doc.resource.ibm_cis_dns_record[name] - - object.get(record, "proxied", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_cis_dns_record.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'proxied' should be defined and set to 'true' to enable DDoS protection", - "keyActualValue": "'proxied' is missing (DNS resolution only, no DDoS protection)", - } +package Cx + +import data.generic.common as common_lib + +# CASO 1: El atributo 'proxied' está explícitamente en false. +CxPolicy[result] { + doc := input.document[i] + record := doc.resource.ibm_cis_dns_record[name] + + record.proxied == false + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_cis_dns_record.%s.proxied", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_cis_dns_record", name, "proxied"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'proxied' should be set to 'true' to enable DDoS protection", + "keyActualValue": "'proxied' is set to 'false'", + } +} + +# CASO 2: El atributo 'proxied' falta (por defecto es false). +CxPolicy[result] { + doc := input.document[i] + record := doc.resource.ibm_cis_dns_record[name] + + object.get(record, "proxied", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_cis_dns_record.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_cis_dns_record", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'proxied' should be defined and set to 'true' to enable DDoS protection", + "keyActualValue": "'proxied' is missing (DNS resolution only, no DDoS protection)", + } } \ No newline at end of file From e450b14a415a251532f5c15231d1c422c7274685 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:14 +0100 Subject: [PATCH 680/900] fix(rego): add searchLine to ibm_cis_waf_enabled_manual --- .../ibm/ibm_cis_waf_enabled_manual/query.rego | 70 ++++++++++--------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/query.rego b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/query.rego index 4c986b46e3f..96e622b0c8c 100644 --- a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/query.rego +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/query.rego @@ -1,34 +1,38 @@ -package Cx - -# CASO 1: El atributo 'waf' existe pero tiene un valor incorrecto (ej. "off"). -CxPolicy[result] { - doc := input.document[i] - settings := doc.resource.ibm_cis_domain_settings[name] - - settings.waf - settings.waf != "on" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_cis_domain_settings.%s.waf", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'waf' attribute should be set to 'on'", - "keyActualValue": sprintf("'waf' attribute is set to '%s'", [settings.waf]), - } -} - -# CASO 2: El atributo 'waf' NO existe en el recurso (valor por defecto varía por plan, se requiere definición explícita). -CxPolicy[result] { - doc := input.document[i] - settings := doc.resource.ibm_cis_domain_settings[name] - - not settings.waf - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_cis_domain_settings.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'waf' attribute should be defined and set to 'on'", - "keyActualValue": "'waf' attribute is missing", - } +package Cx + +import data.generic.common as common_lib + +# CASO 1: El atributo 'waf' existe pero tiene un valor incorrecto (ej. "off"). +CxPolicy[result] { + doc := input.document[i] + settings := doc.resource.ibm_cis_domain_settings[name] + + settings.waf + settings.waf != "on" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_cis_domain_settings.%s.waf", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_cis_domain_settings", name, "waf"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'waf' attribute should be set to 'on'", + "keyActualValue": sprintf("'waf' attribute is set to '%s'", [settings.waf]), + } +} + +# CASO 2: El atributo 'waf' NO existe en el recurso (valor por defecto varía por plan, se requiere definición explícita). +CxPolicy[result] { + doc := input.document[i] + settings := doc.resource.ibm_cis_domain_settings[name] + + not settings.waf + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_cis_domain_settings.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_cis_domain_settings", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'waf' attribute should be defined and set to 'on'", + "keyActualValue": "'waf' attribute is missing", + } } \ No newline at end of file From ba116cb71a2c968d9c640bdbf3ad07faee2f79af Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:15 +0100 Subject: [PATCH 681/900] fix(rego): add searchLine to ibm_cloudant_cmk_encryption_manual --- .../query.rego | 74 ++++++++++--------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/query.rego b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/query.rego index b4949dff8d0..3fb8187aa10 100644 --- a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/query.rego +++ b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/query.rego @@ -1,36 +1,40 @@ -package Cx - -# CASO 1: El bloque 'parameters' está ausente. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.ibm_resource_instance[name] - resource.service == "cloudantnosqldb" - - object.get(resource, "parameters", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_resource_instance.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "Cloudant instance should have a 'parameters' block containing 'key_protect_key'", - "keyActualValue": "The 'parameters' block is missing (using default encryption)", - } -} - -# CASO 2: El bloque 'parameters' existe pero falta 'key_protect_key'. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.ibm_resource_instance[name] - resource.service == "cloudantnosqldb" - - resource.parameters - object.get(resource.parameters, "key_protect_key", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_resource_instance.%s.parameters", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "Cloudant 'parameters' should contain 'key_protect_key' with a valid Key Protect CRN", - "keyActualValue": "'key_protect_key' is missing within the parameters map", - } +package Cx + +import data.generic.common as common_lib + +# CASO 1: El bloque 'parameters' está ausente. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.ibm_resource_instance[name] + resource.service == "cloudantnosqldb" + + object.get(resource, "parameters", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_resource_instance.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_resource_instance", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "Cloudant instance should have a 'parameters' block containing 'key_protect_key'", + "keyActualValue": "The 'parameters' block is missing (using default encryption)", + } +} + +# CASO 2: El bloque 'parameters' existe pero falta 'key_protect_key'. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.ibm_resource_instance[name] + resource.service == "cloudantnosqldb" + + resource.parameters + object.get(resource.parameters, "key_protect_key", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_resource_instance.%s.parameters", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_resource_instance", name, "parameters"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "Cloudant 'parameters' should contain 'key_protect_key' with a valid Key Protect CRN", + "keyActualValue": "'key_protect_key' is missing within the parameters map", + } } \ No newline at end of file From add9dc411aacf926a3ed8173114be7c0b749de81 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:17 +0100 Subject: [PATCH 682/900] fix(rego): add searchLine to ibm_container_cluster_entitlement_check --- .../query.rego | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/query.rego b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/query.rego index 7e661363b45..127fa1c341a 100644 --- a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/query.rego +++ b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/query.rego @@ -1,17 +1,20 @@ -package Cx - -# REGLA: Verificar si el cluster tiene configurada la clave de "entitlement". -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.ibm_container_cluster[name] - - object.get(cluster, "entitlement", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_container_cluster.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'entitlement' attribute should be defined for clusters running IBM Entitled Software", - "keyActualValue": "'entitlement' attribute is missing", - } +package Cx + +import data.generic.common as common_lib + +# REGLA: Verificar si el cluster tiene configurada la clave de "entitlement". +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.ibm_container_cluster[name] + + object.get(cluster, "entitlement", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_container_cluster.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_container_cluster", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'entitlement' attribute should be defined for clusters running IBM Entitled Software", + "keyActualValue": "'entitlement' attribute is missing", + } } \ No newline at end of file From 89d81095900d9e9e7c63ef1956e1f3ed9d8b8be5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:18 +0100 Subject: [PATCH 683/900] fix(rego): add searchLine to ibm_container_registry_va_alerts_missing --- .../query.rego | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/query.rego b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/query.rego index 6137eaab409..231fc9e7254 100644 --- a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/query.rego +++ b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/query.rego @@ -1,19 +1,22 @@ -package Cx - -# REGLA: Verificar si el cluster de Kubernetes tiene configuradas las alertas de vulnerabilidad. -CxPolicy[result] { - doc := input.document[i] - cluster := doc.resource.ibm_container_cluster[name] - - va_notifications := [n | n := input.document[_].resource.ibm_container_va_notification[_]] - - count(va_notifications) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_container_cluster.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "A 'ibm_container_va_notification' resource should be defined to alert on image vulnerabilities", - "keyActualValue": "Vulnerability Advisor notifications are missing for this cluster environment", - } +package Cx + +import data.generic.common as common_lib + +# REGLA: Verificar si el cluster de Kubernetes tiene configuradas las alertas de vulnerabilidad. +CxPolicy[result] { + doc := input.document[i] + cluster := doc.resource.ibm_container_cluster[name] + + va_notifications := [n | n := input.document[_].resource.ibm_container_va_notification[_]] + + count(va_notifications) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_container_cluster.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_container_cluster", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "A 'ibm_container_va_notification' resource should be defined to alert on image vulnerabilities", + "keyActualValue": "Vulnerability Advisor notifications are missing for this cluster environment", + } } \ No newline at end of file From d9ca32bd2e451129d14e6c990d1287d1179a0202 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:19 +0100 Subject: [PATCH 684/900] fix(rego): add searchLine to ibm_database_cmk_encryption_manual --- .../query.rego | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/query.rego b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/query.rego index 7b0a644b906..3fcf44a5904 100644 --- a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/query.rego +++ b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/query.rego @@ -1,17 +1,20 @@ -package Cx - -# CASO 1: Base de datos sin 'key_protect_key'. -CxPolicy[result] { - doc := input.document[i] - db := doc.resource.ibm_database[name] - - object.get(db, "key_protect_key", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_database.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'key_protect_key' attribute should be defined with a Key Protect/HPCS CRN", - "keyActualValue": "'key_protect_key' is missing (using default provider-managed encryption)", - } +package Cx + +import data.generic.common as common_lib + +# CASO 1: Base de datos sin 'key_protect_key'. +CxPolicy[result] { + doc := input.document[i] + db := doc.resource.ibm_database[name] + + object.get(db, "key_protect_key", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_database.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_database", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'key_protect_key' attribute should be defined with a Key Protect/HPCS CRN", + "keyActualValue": "'key_protect_key' is missing (using default provider-managed encryption)", + } } \ No newline at end of file From 5e8b294413a54a933d544e1dc2393f628dea4c91 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:20 +0100 Subject: [PATCH 685/900] fix(rego): add searchLine to ibm_iam_account_ip_restrictions_manual --- .../query.rego | 70 ++++++++++--------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/query.rego b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/query.rego index 7be385c5a10..9973f4405d6 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/query.rego +++ b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/query.rego @@ -1,34 +1,38 @@ -package Cx - -# CASO 1: Restricciones de IP no configuradas (Atributo ausente). -CxPolicy[result] { - doc := input.document[i] - settings := doc.resource.ibm_iam_account_settings[name] - - object.get(settings, "allowed_ip_addresses", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_iam_account_settings.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'allowed_ip_addresses' should be defined with a list of trusted IPs", - "keyActualValue": "'allowed_ip_addresses' is missing (access allowed from anywhere)", - } -} - -# CASO 2: Restricciones definidas pero lista vacía. -CxPolicy[result] { - doc := input.document[i] - settings := doc.resource.ibm_iam_account_settings[name] - - ips := settings.allowed_ip_addresses - count(ips) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_iam_account_settings.%s.allowed_ip_addresses", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'allowed_ip_addresses' should contain at least one trusted IP/Subnet", - "keyActualValue": "'allowed_ip_addresses' is empty", - } +package Cx + +import data.generic.common as common_lib + +# CASO 1: Restricciones de IP no configuradas (Atributo ausente). +CxPolicy[result] { + doc := input.document[i] + settings := doc.resource.ibm_iam_account_settings[name] + + object.get(settings, "allowed_ip_addresses", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_iam_account_settings.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_iam_account_settings", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'allowed_ip_addresses' should be defined with a list of trusted IPs", + "keyActualValue": "'allowed_ip_addresses' is missing (access allowed from anywhere)", + } +} + +# CASO 2: Restricciones definidas pero lista vacía. +CxPolicy[result] { + doc := input.document[i] + settings := doc.resource.ibm_iam_account_settings[name] + + ips := settings.allowed_ip_addresses + count(ips) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_iam_account_settings.%s.allowed_ip_addresses", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_iam_account_settings", name, "allowed_ip_addresses"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'allowed_ip_addresses' should contain at least one trusted IP/Subnet", + "keyActualValue": "'allowed_ip_addresses' is empty", + } } \ No newline at end of file From beb88f29a8b029785f6835c226e53f6ccadc89d2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:22 +0100 Subject: [PATCH 686/900] fix(rego): add searchLine to ibm_iam_session_expiration_too_long --- .../query.rego | 72 ++++++++++--------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/query.rego b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/query.rego index d374d167dda..3e6476c9d32 100644 --- a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/query.rego +++ b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/query.rego @@ -1,35 +1,39 @@ -package Cx - -# REGLA 1: Falta el atributo 'session_expiration_in_seconds'. -CxPolicy[result] { - doc := input.document[i] - settings := doc.resource.ibm_iam_account_settings[name] - - object.get(settings, "session_expiration_in_seconds", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_iam_account_settings.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'session_expiration_in_seconds' should be defined and set to 3600 (1 hour) or less", - "keyActualValue": "'session_expiration_in_seconds' is missing (using insecure default)", - } -} - -# REGLA 2: La sesión dura más de 1 hora (3600 segundos). -CxPolicy[result] { - doc := input.document[i] - settings := doc.resource.ibm_iam_account_settings[name] - - expiration := to_number(settings.session_expiration_in_seconds) - - expiration > 3600 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_iam_account_settings.%s.session_expiration_in_seconds", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'session_expiration_in_seconds' should be <= 3600", - "keyActualValue": sprintf("'session_expiration_in_seconds' is set to '%v'", [expiration]), - } +package Cx + +import data.generic.common as common_lib + +# REGLA 1: Falta el atributo 'session_expiration_in_seconds'. +CxPolicy[result] { + doc := input.document[i] + settings := doc.resource.ibm_iam_account_settings[name] + + object.get(settings, "session_expiration_in_seconds", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_iam_account_settings.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_iam_account_settings", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'session_expiration_in_seconds' should be defined and set to 3600 (1 hour) or less", + "keyActualValue": "'session_expiration_in_seconds' is missing (using insecure default)", + } +} + +# REGLA 2: La sesión dura más de 1 hora (3600 segundos). +CxPolicy[result] { + doc := input.document[i] + settings := doc.resource.ibm_iam_account_settings[name] + + expiration := to_number(settings.session_expiration_in_seconds) + + expiration > 3600 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_iam_account_settings.%s.session_expiration_in_seconds", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_iam_account_settings", name, "session_expiration_in_seconds"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'session_expiration_in_seconds' should be <= 3600", + "keyActualValue": sprintf("'session_expiration_in_seconds' is set to '%v'", [expiration]), + } } \ No newline at end of file From 81c81405cd8a8afde56fae32e8faa7d75887d3dd Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:23 +0100 Subject: [PATCH 687/900] fix(rego): add searchLine to ibm_iks_cluster_logging_disabled --- .../query.rego | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/query.rego b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/query.rego index 26b576f814a..11ec4f64393 100644 --- a/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_logging_disabled/query.rego @@ -1,21 +1,24 @@ -package Cx - -CxPolicy[result] { - doc := input.document[i] - _ := doc.resource.ibm_container_cluster[cluster_name] - - matching_configs := [config | - config := input.document[_].resource.ibm_ob_logging_config[_] - contains(config.scope, cluster_name) - ] - - count(matching_configs) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_container_cluster.%s", [cluster_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "ibm_container_cluster should have an associated ibm_ob_logging_config resource", - "keyActualValue": "ibm_container_cluster does not have an associated ibm_ob_logging_config resource", - } +package Cx + +import data.generic.common as common_lib + +CxPolicy[result] { + doc := input.document[i] + _ := doc.resource.ibm_container_cluster[cluster_name] + + matching_configs := [config | + config := input.document[_].resource.ibm_ob_logging_config[_] + contains(config.scope, cluster_name) + ] + + count(matching_configs) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_container_cluster.%s", [cluster_name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_container_cluster", cluster_name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "ibm_container_cluster should have an associated ibm_ob_logging_config resource", + "keyActualValue": "ibm_container_cluster does not have an associated ibm_ob_logging_config resource", + } } \ No newline at end of file From be1d55b7b89d1e4cde643344297e076e13a2b160 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:25 +0100 Subject: [PATCH 688/900] fix(rego): add searchLine to ibm_iks_cluster_monitoring_disabled --- .../query.rego | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/query.rego b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/query.rego index a0006913788..3d67f2f6865 100644 --- a/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_iks_cluster_monitoring_disabled/query.rego @@ -1,22 +1,25 @@ -package Cx - -# REGLA: Detectar clústeres de IKS sin configuración de monitorización asociada. -CxPolicy[result] { - doc := input.document[i] - _ := doc.resource.ibm_container_cluster[cluster_name] - - matching_configs := [config | - config := input.document[_].resource.ibm_ob_monitoring_config[_] - contains(config.scope, cluster_name) - ] - - count(matching_configs) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_container_cluster.%s", [cluster_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "ibm_container_cluster should have an associated ibm_ob_monitoring_config resource", - "keyActualValue": "ibm_container_cluster does not have an associated ibm_ob_monitoring_config resource", - } +package Cx + +import data.generic.common as common_lib + +# REGLA: Detectar clústeres de IKS sin configuración de monitorización asociada. +CxPolicy[result] { + doc := input.document[i] + _ := doc.resource.ibm_container_cluster[cluster_name] + + matching_configs := [config | + config := input.document[_].resource.ibm_ob_monitoring_config[_] + contains(config.scope, cluster_name) + ] + + count(matching_configs) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_container_cluster.%s", [cluster_name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_container_cluster", cluster_name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "ibm_container_cluster should have an associated ibm_ob_monitoring_config resource", + "keyActualValue": "ibm_container_cluster does not have an associated ibm_ob_monitoring_config resource", + } } \ No newline at end of file From 70dfa9ed22fedfac2b0c2de89d30a63ca830828a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:26 +0100 Subject: [PATCH 689/900] fix(rego): add searchLine to ibm_instance_os_disk_encryption_manual --- .../query.rego | 80 ++++++++++--------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/query.rego b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/query.rego index 0ad2c6fd738..0693449d1b0 100644 --- a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/query.rego +++ b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/query.rego @@ -1,39 +1,43 @@ -package Cx - -ensure_array(x) = x { is_array(x) } -ensure_array(x) = [x] { not is_array(x) } - -# CASO 1: Bloque 'boot_volume' totalmente ausente. -CxPolicy[result] { - doc := input.document[i] - instance := doc.resource.ibm_is_instance[name] - - not instance.boot_volume - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_is_instance.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'boot_volume' block should be defined with 'encryption' set to a CRN", - "keyActualValue": "'boot_volume' block is missing (using default encryption)", - } -} - -# CASO 2: Bloque 'boot_volume' presente, pero falta 'encryption'. -CxPolicy[result] { - doc := input.document[i] - instance := doc.resource.ibm_is_instance[name] - - boot_volumes := ensure_array(instance.boot_volume) - boot_vol := boot_volumes[_] - - object.get(boot_vol, "encryption", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_is_instance.%s.boot_volume", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'boot_volume.encryption' attribute should be defined with a Key Protect/HPCS CRN", - "keyActualValue": "'encryption' is missing in boot_volume (using default encryption)", - } +package Cx + +import data.generic.common as common_lib + +ensure_array(x) = x { is_array(x) } +ensure_array(x) = [x] { not is_array(x) } + +# CASO 1: Bloque 'boot_volume' totalmente ausente. +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.ibm_is_instance[name] + + not instance.boot_volume + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_is_instance.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_is_instance", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'boot_volume' block should be defined with 'encryption' set to a CRN", + "keyActualValue": "'boot_volume' block is missing (using default encryption)", + } +} + +# CASO 2: Bloque 'boot_volume' presente, pero falta 'encryption'. +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.ibm_is_instance[name] + + boot_volumes := ensure_array(instance.boot_volume) + boot_vol := boot_volumes[_] + + object.get(boot_vol, "encryption", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_is_instance.%s.boot_volume", [name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_is_instance", name, "boot_volume"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'boot_volume.encryption' attribute should be defined with a Key Protect/HPCS CRN", + "keyActualValue": "'encryption' is missing in boot_volume (using default encryption)", + } } \ No newline at end of file From 052f4527db3e265dfc6463c6d687c652fca59d6c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:27 +0100 Subject: [PATCH 690/900] fix(rego): add searchLine to ibm_kms_key_rotation_disabled --- .../ibm_kms_key_rotation_disabled/query.rego | 97 ++++++++++--------- 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/query.rego b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/query.rego index 1549c0c0b34..2fcede3668c 100644 --- a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/query.rego @@ -1,47 +1,52 @@ -package Cx - -# REGLA 1: El bloque 'rotation_policy' está completamente ausente. -CxPolicy[result] { - key := input.document[i].resource.ibm_kms_key[key_name] - - not key.rotation_policy - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.ibm_kms_key.%s", [key_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'rotation_policy' block should be present and configured", - "keyActualValue": "'rotation_policy' block is missing", - } -} - -# REGLA 2: El bloque 'rotation_policy' existe, pero le falta 'rotation_interval_month'. -CxPolicy[result] { - key := input.document[i].resource.ibm_kms_key[key_name] - - policy := key.rotation_policy - not policy.rotation_interval_month - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.ibm_kms_key.%s.rotation_policy", [key_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'rotation_interval_month' should be defined within the rotation policy", - "keyActualValue": "'rotation_interval_month' is missing", - } -} - -# REGLA 3: 'rotation_interval_month' está explícitamente configurado como 0. -CxPolicy[result] { - key := input.document[i].resource.ibm_kms_key[key_name] - - key.rotation_policy.rotation_interval_month == 0 - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.ibm_kms_key.%s.rotation_policy.rotation_interval_month", [key_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'rotation_interval_month' should be a value between 1 and 12", - "keyActualValue": "'rotation_interval_month' is set to 0, disabling rotation", - } +package Cx + +import data.generic.common as common_lib + +# REGLA 1: El bloque 'rotation_policy' está completamente ausente. +CxPolicy[result] { + key := input.document[i].resource.ibm_kms_key[key_name] + + not key.rotation_policy + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_kms_key.%s", [key_name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_kms_key", key_name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'rotation_policy' block should be present and configured", + "keyActualValue": "'rotation_policy' block is missing", + } +} + +# REGLA 2: El bloque 'rotation_policy' existe, pero le falta 'rotation_interval_month'. +CxPolicy[result] { + key := input.document[i].resource.ibm_kms_key[key_name] + + policy := key.rotation_policy + not policy.rotation_interval_month + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_kms_key.%s.rotation_policy", [key_name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_kms_key", key_name, "rotation_policy"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'rotation_interval_month' should be defined within the rotation policy", + "keyActualValue": "'rotation_interval_month' is missing", + } +} + +# REGLA 3: 'rotation_interval_month' está explícitamente configurado como 0. +CxPolicy[result] { + key := input.document[i].resource.ibm_kms_key[key_name] + + key.rotation_policy.rotation_interval_month == 0 + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_kms_key.%s.rotation_policy.rotation_interval_month", [key_name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_kms_key", key_name, "rotation_policy", "rotation_interval_month"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'rotation_interval_month' should be a value between 1 and 12", + "keyActualValue": "'rotation_interval_month' is set to 0, disabling rotation", + } } \ No newline at end of file From 1dceb30562da1a58fccdc7bec184ae82e983d7fe Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:29 +0100 Subject: [PATCH 691/900] fix(rego): add searchLine to ibm_logdna_archiving_disabled --- .../ibm_logdna_archiving_disabled/query.rego | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/query.rego b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/query.rego index 1a58771346c..dce95c0ba77 100644 --- a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/query.rego @@ -1,22 +1,25 @@ -package Cx - -# REGLA: Detectar instancias de LogDNA que no tienen un recurso de archivado asociado. -CxPolicy[result] { - doc := input.document[i] - _ := doc.resource.ibm_logdna_instance[instance_name] - - matching_archives := [archive | - archive := input.document[_].resource.ibm_logdna_archive[_] - contains(archive.instance_id, instance_name) - ] - - count(matching_archives) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_logdna_instance.%s", [instance_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "ibm_logdna_instance should have an associated ibm_logdna_archive resource", - "keyActualValue": "ibm_logdna_instance does not have an associated ibm_logdna_archive resource", - } +package Cx + +import data.generic.common as common_lib + +# REGLA: Detectar instancias de LogDNA que no tienen un recurso de archivado asociado. +CxPolicy[result] { + doc := input.document[i] + _ := doc.resource.ibm_logdna_instance[instance_name] + + matching_archives := [archive | + archive := input.document[_].resource.ibm_logdna_archive[_] + contains(archive.instance_id, instance_name) + ] + + count(matching_archives) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_logdna_instance.%s", [instance_name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_logdna_instance", instance_name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "ibm_logdna_instance should have an associated ibm_logdna_archive resource", + "keyActualValue": "ibm_logdna_instance does not have an associated ibm_logdna_archive resource", + } } \ No newline at end of file From 14ec72b69157feb8bb38c37b25153984fb4a2bda Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:30 +0100 Subject: [PATCH 692/900] fix(rego): add searchLine to ibm_logdna_view_without_alert --- .../ibm_logdna_view_without_alert/query.rego | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/query.rego b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/query.rego index b49190804fb..06565b0b143 100644 --- a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/query.rego +++ b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/query.rego @@ -1,22 +1,25 @@ -package Cx - -# REGLA: Detectar vistas de LogDNA que no tienen ninguna alerta asociada. -CxPolicy[result] { - doc := input.document[i] - view := doc.resource.ibm_logdna_view[view_name] - - matching_alerts := [alert | - alert := input.document[_].resource.ibm_logdna_alert[_] - contains(alert.view, view_name) - ] - - count(matching_alerts) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.ibm_logdna_view.%s", [view_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "ibm_logdna_view should have an associated ibm_logdna_alert", - "keyActualValue": "ibm_logdna_view does not have an associated ibm_logdna_alert", - } +package Cx + +import data.generic.common as common_lib + +# REGLA: Detectar vistas de LogDNA que no tienen ninguna alerta asociada. +CxPolicy[result] { + doc := input.document[i] + view := doc.resource.ibm_logdna_view[view_name] + + matching_alerts := [alert | + alert := input.document[_].resource.ibm_logdna_alert[_] + contains(alert.view, view_name) + ] + + count(matching_alerts) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.ibm_logdna_view.%s", [view_name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_logdna_view", view_name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "ibm_logdna_view should have an associated ibm_logdna_alert", + "keyActualValue": "ibm_logdna_view does not have an associated ibm_logdna_alert", + } } \ No newline at end of file From 7f6ff2047079df1b1d84c543c2c9813e05979c7f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:31 +0100 Subject: [PATCH 693/900] fix(rego): add searchLine to oci_compute_legacy_metadata_enabled --- .../query.rego | 99 ++++++++++--------- 1 file changed, 52 insertions(+), 47 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/query.rego b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/query.rego index 6810f9c2967..0786620bb8a 100644 --- a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/query.rego +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/query.rego @@ -1,48 +1,53 @@ -package Cx - -# REGLA 1: Falta el bloque 'agent_config' por completo. -CxPolicy[result] { - instance := input.document[i].resource.oci_core_instance[instance_name] - - not instance.agent_config - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_core_instance.%s", [instance_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'agent_config' block should be defined", - "keyActualValue": "'agent_config' block is missing", - } -} - -# REGLA 2: Existe 'agent_config', pero falta el atributo dentro. -CxPolicy[result] { - instance := input.document[i].resource.oci_core_instance[instance_name] - agent_config := instance.agent_config - - object.get(agent_config, "are_legacy_imds_endpoints_disabled", null) == null - - result := { - "documentId": input.document[i].id, - # AQUI ESTA EL CAMBIO: Apuntamos al bloque agent_config - "searchKey": sprintf("resource.oci_core_instance.%s.agent_config", [instance_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'are_legacy_imds_endpoints_disabled' should be present and set to 'true'", - "keyActualValue": "'are_legacy_imds_endpoints_disabled' is missing inside 'agent_config'", - } -} - -# REGLA 3: El atributo existe pero es 'false'. -CxPolicy[result] { - instance := input.document[i].resource.oci_core_instance[instance_name] - - instance.agent_config.are_legacy_imds_endpoints_disabled == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_core_instance.%s.agent_config.are_legacy_imds_endpoints_disabled", [instance_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'are_legacy_imds_endpoints_disabled' attribute should be 'true'", - "keyActualValue": "'are_legacy_imds_endpoints_disabled' attribute is 'false'", - } +package Cx + +import data.generic.common as common_lib + +# REGLA 1: Falta el bloque 'agent_config' por completo. +CxPolicy[result] { + instance := input.document[i].resource.oci_core_instance[instance_name] + + not instance.agent_config + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_core_instance.%s", [instance_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_core_instance", instance_name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'agent_config' block should be defined", + "keyActualValue": "'agent_config' block is missing", + } +} + +# REGLA 2: Existe 'agent_config', pero falta el atributo dentro. +CxPolicy[result] { + instance := input.document[i].resource.oci_core_instance[instance_name] + agent_config := instance.agent_config + + object.get(agent_config, "are_legacy_imds_endpoints_disabled", null) == null + + result := { + "documentId": input.document[i].id, + # AQUI ESTA EL CAMBIO: Apuntamos al bloque agent_config + "searchKey": sprintf("resource.oci_core_instance.%s.agent_config", [instance_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_core_instance", instance_name, "agent_config"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'are_legacy_imds_endpoints_disabled' should be present and set to 'true'", + "keyActualValue": "'are_legacy_imds_endpoints_disabled' is missing inside 'agent_config'", + } +} + +# REGLA 3: El atributo existe pero es 'false'. +CxPolicy[result] { + instance := input.document[i].resource.oci_core_instance[instance_name] + + instance.agent_config.are_legacy_imds_endpoints_disabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_core_instance.%s.agent_config.are_legacy_imds_endpoints_disabled", [instance_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_core_instance", instance_name, "agent_config", "are_legacy_imds_endpoints_disabled"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'are_legacy_imds_endpoints_disabled' attribute should be 'true'", + "keyActualValue": "'are_legacy_imds_endpoints_disabled' attribute is 'false'", + } } \ No newline at end of file From 2a660a6ec2823d2dcfd358c145dd11ed5fa0a95e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:32 +0100 Subject: [PATCH 694/900] fix(rego): add searchLine to oci_iam_password_expiration_manual --- .../query.rego | 97 ++++++++++--------- 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/query.rego b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/query.rego index 61245d9ec1e..eff2729dac6 100644 --- a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/query.rego +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/query.rego @@ -1,47 +1,52 @@ -package Cx - -# CASO 1: Identity Domains - Expiración (password_expires_after) > 365. -CxPolicy[result] { - doc := input.document[i] - policy := doc.resource.oci_identity_domains_password_policy[name] - - policy.password_expires_after > 365 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_identity_domains_password_policy.%s.password_expires_after", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'password_expires_after' should be <= 365", - "keyActualValue": sprintf("'password_expires_after' is %d", [policy.password_expires_after]), - } -} - -# CASO 2: Identity Domains - Atributo faltante. -CxPolicy[result] { - doc := input.document[i] - policy := doc.resource.oci_identity_domains_password_policy[name] - - object.get(policy, "password_expires_after", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_identity_domains_password_policy.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'password_expires_after' should be defined (<= 365)", - "keyActualValue": "'password_expires_after' is missing", - } -} - -# CASO 3: IAM Clásico (Legacy) - Manual. -CxPolicy[result] { - doc := input.document[i] - _ := doc.resource.oci_identity_authentication_policy[name] - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_identity_authentication_policy.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "Password expiration should be enforced (<= 365 days)", - "keyActualValue": "Legacy resource does not support password expiration config in Terraform. Manual console check required.", - } +package Cx + +import data.generic.common as common_lib + +# CASO 1: Identity Domains - Expiración (password_expires_after) > 365. +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.oci_identity_domains_password_policy[name] + + policy.password_expires_after > 365 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_domains_password_policy.%s.password_expires_after", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_identity_domains_password_policy", name, "password_expires_after"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'password_expires_after' should be <= 365", + "keyActualValue": sprintf("'password_expires_after' is %d", [policy.password_expires_after]), + } +} + +# CASO 2: Identity Domains - Atributo faltante. +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.oci_identity_domains_password_policy[name] + + object.get(policy, "password_expires_after", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_domains_password_policy.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_identity_domains_password_policy", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'password_expires_after' should be defined (<= 365)", + "keyActualValue": "'password_expires_after' is missing", + } +} + +# CASO 3: IAM Clásico (Legacy) - Manual. +CxPolicy[result] { + doc := input.document[i] + _ := doc.resource.oci_identity_authentication_policy[name] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_authentication_policy.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_identity_authentication_policy", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "Password expiration should be enforced (<= 365 days)", + "keyActualValue": "Legacy resource does not support password expiration config in Terraform. Manual console check required.", + } } \ No newline at end of file From 2109024d3caaaf52545df920dba45fbf1b4f23e8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:34 +0100 Subject: [PATCH 695/900] fix(rego): add searchLine to oci_iam_password_policy_length --- .../oci_iam_password_policy_length/query.rego | 127 +++++++++--------- 1 file changed, 66 insertions(+), 61 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/query.rego b/assets/queries/terraform/oci/oci_iam_password_policy_length/query.rego index 8346e24f0bc..a1c6a3eae39 100644 --- a/assets/queries/terraform/oci/oci_iam_password_policy_length/query.rego +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/query.rego @@ -1,62 +1,67 @@ -package Cx - -ensure_array(x) = x { is_array(x) } -ensure_array(x) = [x] { is_object(x) } - -# CASO 1: El bloque 'password_policy' EXISTE, pero el valor es menor a 14. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.oci_identity_authentication_policy[name] - - resource.password_policy - policies := ensure_array(resource.password_policy) - policy := policies[_] - - policy.minimum_password_length - - to_number(policy.minimum_password_length) < 14 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_identity_authentication_policy.%s.password_policy.minimum_password_length", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'minimum_password_length' should be 14 or greater", - "keyActualValue": sprintf("'minimum_password_length' is %d", [to_number(policy.minimum_password_length)]), - } -} - -# CASO 2: El bloque 'password_policy' EXISTE, pero FALTA el atributo 'minimum_password_length'. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.oci_identity_authentication_policy[name] - - resource.password_policy - policies := ensure_array(resource.password_policy) - policy := policies[_] - - object.get(policy, "minimum_password_length", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_identity_authentication_policy.%s.password_policy", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'minimum_password_length' should be explicitly defined (>= 14)", - "keyActualValue": "'minimum_password_length' is missing (using default)", - } -} - -# CASO 3: El bloque 'password_policy' NO EXISTE en absoluto. -CxPolicy[result] { - doc := input.document[i] - resource := doc.resource.oci_identity_authentication_policy[name] - - not resource.password_policy - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_identity_authentication_policy.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'password_policy' block should be defined with 'minimum_password_length' >= 14", - "keyActualValue": "'password_policy' block is missing", - } +package Cx + +import data.generic.common as common_lib + +ensure_array(x) = x { is_array(x) } +ensure_array(x) = [x] { is_object(x) } + +# CASO 1: El bloque 'password_policy' EXISTE, pero el valor es menor a 14. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.oci_identity_authentication_policy[name] + + resource.password_policy + policies := ensure_array(resource.password_policy) + policy := policies[_] + + policy.minimum_password_length + + to_number(policy.minimum_password_length) < 14 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_authentication_policy.%s.password_policy.minimum_password_length", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_identity_authentication_policy", name, "password_policy", "minimum_password_length"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'minimum_password_length' should be 14 or greater", + "keyActualValue": sprintf("'minimum_password_length' is %d", [to_number(policy.minimum_password_length)]), + } +} + +# CASO 2: El bloque 'password_policy' EXISTE, pero FALTA el atributo 'minimum_password_length'. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.oci_identity_authentication_policy[name] + + resource.password_policy + policies := ensure_array(resource.password_policy) + policy := policies[_] + + object.get(policy, "minimum_password_length", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_authentication_policy.%s.password_policy", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_identity_authentication_policy", name, "password_policy"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'minimum_password_length' should be explicitly defined (>= 14)", + "keyActualValue": "'minimum_password_length' is missing (using default)", + } +} + +# CASO 3: El bloque 'password_policy' NO EXISTE en absoluto. +CxPolicy[result] { + doc := input.document[i] + resource := doc.resource.oci_identity_authentication_policy[name] + + not resource.password_policy + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_authentication_policy.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_identity_authentication_policy", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'password_policy' block should be defined with 'minimum_password_length' >= 14", + "keyActualValue": "'password_policy' block is missing", + } } \ No newline at end of file From f06f8dd0e987c847dbbdf679befb182779bb9034 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:35 +0100 Subject: [PATCH 696/900] fix(rego): add searchLine to oci_iam_password_reuse_manual --- .../oci_iam_password_reuse_manual/query.rego | 97 ++++++++++--------- 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/query.rego b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/query.rego index 2eee491d363..61850f3e67e 100644 --- a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/query.rego +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/query.rego @@ -1,47 +1,52 @@ -package Cx - -# CASO 1: Identity Domains - Historial insuficiente (< 24). -CxPolicy[result] { - doc := input.document[i] - policy := doc.resource.oci_identity_domains_password_policy[name] - - policy.num_passwords_in_history < 24 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_identity_domains_password_policy.%s.num_passwords_in_history", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'num_passwords_in_history' should be >= 24", - "keyActualValue": sprintf("Current history size is %d", [policy.num_passwords_in_history]), - } -} - -# CASO 2: Identity Domains - Atributo faltante. -CxPolicy[result] { - doc := input.document[i] - policy := doc.resource.oci_identity_domains_password_policy[name] - - object.get(policy, "num_passwords_in_history", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_identity_domains_password_policy.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'num_passwords_in_history' should be defined (>= 24)", - "keyActualValue": "'num_passwords_in_history' is missing", - } -} - -# CASO 3: IAM Clásico (Legacy) - Manual. -CxPolicy[result] { - doc := input.document[i] - _ := doc.resource.oci_identity_authentication_policy[name] - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_identity_authentication_policy.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "Password reuse prevention should be enabled (History >= 24)", - "keyActualValue": "Legacy resource does not support password history settings in Terraform. Manual console check required.", - } +package Cx + +import data.generic.common as common_lib + +# CASO 1: Identity Domains - Historial insuficiente (< 24). +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.oci_identity_domains_password_policy[name] + + policy.num_passwords_in_history < 24 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_domains_password_policy.%s.num_passwords_in_history", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_identity_domains_password_policy", name, "num_passwords_in_history"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'num_passwords_in_history' should be >= 24", + "keyActualValue": sprintf("Current history size is %d", [policy.num_passwords_in_history]), + } +} + +# CASO 2: Identity Domains - Atributo faltante. +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.oci_identity_domains_password_policy[name] + + object.get(policy, "num_passwords_in_history", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_domains_password_policy.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_identity_domains_password_policy", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'num_passwords_in_history' should be defined (>= 24)", + "keyActualValue": "'num_passwords_in_history' is missing", + } +} + +# CASO 3: IAM Clásico (Legacy) - Manual. +CxPolicy[result] { + doc := input.document[i] + _ := doc.resource.oci_identity_authentication_policy[name] + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_authentication_policy.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_identity_authentication_policy", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "Password reuse prevention should be enabled (History >= 24)", + "keyActualValue": "Legacy resource does not support password history settings in Terraform. Manual console check required.", + } } \ No newline at end of file From 6490ed911dce7551d761dc65b169587d35120f77 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:36 +0100 Subject: [PATCH 697/900] fix(rego): add searchLine to oci_iam_service_admins_manual --- .../oci_iam_service_admins_manual/query.rego | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_service_admins_manual/query.rego b/assets/queries/terraform/oci/oci_iam_service_admins_manual/query.rego index 5e2ce35faa0..f6a71857767 100644 --- a/assets/queries/terraform/oci/oci_iam_service_admins_manual/query.rego +++ b/assets/queries/terraform/oci/oci_iam_service_admins_manual/query.rego @@ -1,19 +1,22 @@ -package Cx - -# REGLA: Auditoría Manual de Políticas de Gestión (Service Admins). -CxPolicy[result] { - doc := input.document[i] - policy := doc.resource.oci_identity_policy[name] - - statement := policy.statements[_] - - regex.match("(?i)\\bmanage\\b", statement) - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_identity_policy.%s.statements", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "Policy should grant 'manage' on specific families to specific groups (Manual Review)", - "keyActualValue": sprintf("Policy statement grants management privileges: '%s'. Manual review required.", [statement]), - } +package Cx + +import data.generic.common as common_lib + +# REGLA: Auditoría Manual de Políticas de Gestión (Service Admins). +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.oci_identity_policy[name] + + statement := policy.statements[_] + + regex.match("(?i)\\bmanage\\b", statement) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_policy.%s.statements", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_identity_policy", name, "statements"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "Policy should grant 'manage' on specific families to specific groups (Manual Review)", + "keyActualValue": sprintf("Policy statement grants management privileges: '%s'. Manual review required.", [statement]), + } } \ No newline at end of file From 7223ab3baa4f37fb07fce37284317646ba5f192c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:38 +0100 Subject: [PATCH 698/900] fix(rego): add searchLine to oci_instance_transit_encryption --- .../query.rego | 119 +++++++++--------- 1 file changed, 62 insertions(+), 57 deletions(-) diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/query.rego b/assets/queries/terraform/oci/oci_instance_transit_encryption/query.rego index 2dac4c0608d..5bd4e5f6031 100644 --- a/assets/queries/terraform/oci/oci_instance_transit_encryption/query.rego +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/query.rego @@ -1,58 +1,63 @@ -package Cx - -ensure_array(x) = x { is_array(x) } -ensure_array(x) = [x] { is_object(x) } - -# CASO 1: El bloque launch_options existe, pero la opción está explícitamente en FALSE. -CxPolicy[result] { - doc := input.document[i] - instance := doc.resource.oci_core_instance[name] - - options := ensure_array(instance.launch_options) - opt := options[_] - - opt.is_pv_encryption_in_transit_enabled == false - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_core_instance.%s.launch_options.is_pv_encryption_in_transit_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'is_pv_encryption_in_transit_enabled' should be set to true", - "keyActualValue": "'is_pv_encryption_in_transit_enabled' is set to false", - } -} - -# CASO 2: El bloque launch_options existe, pero FALTA el atributo (default es false/inseguro). -CxPolicy[result] { - doc := input.document[i] - instance := doc.resource.oci_core_instance[name] - - options := ensure_array(instance.launch_options) - opt := options[_] - - object.get(opt, "is_pv_encryption_in_transit_enabled", "undefined") == "undefined" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_core_instance.%s.launch_options", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'is_pv_encryption_in_transit_enabled' should be defined and set to true", - "keyActualValue": "'is_pv_encryption_in_transit_enabled' is missing", - } -} - -# CASO 3: FALTA el bloque launch_options completo. -CxPolicy[result] { - doc := input.document[i] - instance := doc.resource.oci_core_instance[name] - - not instance.launch_options - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_core_instance.%s", [name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'launch_options' block with 'is_pv_encryption_in_transit_enabled = true' should be defined", - "keyActualValue": "'launch_options' block is missing", - } +package Cx + +import data.generic.common as common_lib + +ensure_array(x) = x { is_array(x) } +ensure_array(x) = [x] { is_object(x) } + +# CASO 1: El bloque launch_options existe, pero la opción está explícitamente en FALSE. +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.oci_core_instance[name] + + options := ensure_array(instance.launch_options) + opt := options[_] + + opt.is_pv_encryption_in_transit_enabled == false + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_core_instance.%s.launch_options.is_pv_encryption_in_transit_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_core_instance", name, "launch_options", "is_pv_encryption_in_transit_enabled"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_pv_encryption_in_transit_enabled' should be set to true", + "keyActualValue": "'is_pv_encryption_in_transit_enabled' is set to false", + } +} + +# CASO 2: El bloque launch_options existe, pero FALTA el atributo (default es false/inseguro). +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.oci_core_instance[name] + + options := ensure_array(instance.launch_options) + opt := options[_] + + object.get(opt, "is_pv_encryption_in_transit_enabled", "undefined") == "undefined" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_core_instance.%s.launch_options", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_core_instance", name, "launch_options"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'is_pv_encryption_in_transit_enabled' should be defined and set to true", + "keyActualValue": "'is_pv_encryption_in_transit_enabled' is missing", + } +} + +# CASO 3: FALTA el bloque launch_options completo. +CxPolicy[result] { + doc := input.document[i] + instance := doc.resource.oci_core_instance[name] + + not instance.launch_options + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_core_instance.%s", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_core_instance", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'launch_options' block with 'is_pv_encryption_in_transit_enabled = true' should be defined", + "keyActualValue": "'launch_options' block is missing", + } } \ No newline at end of file From e22092900e0b596010c40d16e6c41bdeb3d1a617 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:39 +0100 Subject: [PATCH 699/900] fix(rego): add searchLine to oci_objectstorage_bucket_logging_enabled --- .../query.rego | 66 ++++++++++--------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/query.rego b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/query.rego index 8a11d86be3d..0b570b9924f 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/query.rego +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/query.rego @@ -1,32 +1,36 @@ -package Cx - -# REGLA 1: El atributo 'object_events_enabled' está ausente (MissingAttribute). -# Por defecto en OCI Terraform es false, así que su ausencia es un riesgo. -CxPolicy[result] { - bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] - - object.get(bucket, "object_events_enabled", null) == null - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_objectstorage_bucket.%s", [bucket_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'object_events_enabled' should be present and set to 'true'", - "keyActualValue": "'object_events_enabled' is missing and defaults to 'false'", - } -} - -# REGLA 2: El atributo 'object_events_enabled' está explícitamente en 'false' (IncorrectValue). -CxPolicy[result] { - bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] - - bucket.object_events_enabled == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_objectstorage_bucket.%s.object_events_enabled", [bucket_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'object_events_enabled' attribute should be 'true'", - "keyActualValue": "'object_events_enabled' attribute is 'false'", - } +package Cx + +import data.generic.common as common_lib + +# REGLA 1: El atributo 'object_events_enabled' está ausente (MissingAttribute). +# Por defecto en OCI Terraform es false, así que su ausencia es un riesgo. +CxPolicy[result] { + bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] + + object.get(bucket, "object_events_enabled", null) == null + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_objectstorage_bucket.%s", [bucket_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_objectstorage_bucket", bucket_name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'object_events_enabled' should be present and set to 'true'", + "keyActualValue": "'object_events_enabled' is missing and defaults to 'false'", + } +} + +# REGLA 2: El atributo 'object_events_enabled' está explícitamente en 'false' (IncorrectValue). +CxPolicy[result] { + bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] + + bucket.object_events_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_objectstorage_bucket.%s.object_events_enabled", [bucket_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_objectstorage_bucket", bucket_name, "object_events_enabled"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'object_events_enabled' attribute should be 'true'", + "keyActualValue": "'object_events_enabled' attribute is 'false'", + } } \ No newline at end of file From 05c549adcf997e8579fdb892818fbf66b35cd82c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:40 +0100 Subject: [PATCH 700/900] fix(rego): add searchLine to oci_objectstorage_bucket_versioning_disabled --- .../query.rego | 70 ++++++++++--------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/query.rego b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/query.rego index e280e479a55..d28c37f7c62 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/query.rego +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/query.rego @@ -1,34 +1,38 @@ -package Cx - -# REGLA 1: El atributo 'versioning' está ausente en el bucket. -# Por defecto, si no se especifica, el versionado está deshabilitado. -CxPolicy[result] { - bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] - - object.get(bucket, "versioning", null) == null - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_objectstorage_bucket.%s", [bucket_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'versioning' attribute should be present and set to 'Enabled'", - "keyActualValue": "'versioning' attribute is missing, disabling versioning", - } -} - -# REGLA 2: El atributo 'versioning' existe pero no es 'Enabled'. -# Puede ser 'Disabled' o 'Suspended'. -CxPolicy[result] { - bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] - - object.get(bucket, "versioning", null) != null - bucket.versioning != "Enabled" - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_objectstorage_bucket.%s.versioning", [bucket_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'versioning' attribute should be 'Enabled'", - "keyActualValue": sprintf("'versioning' attribute is '%s'", [bucket.versioning]), - } +package Cx + +import data.generic.common as common_lib + +# REGLA 1: El atributo 'versioning' está ausente en el bucket. +# Por defecto, si no se especifica, el versionado está deshabilitado. +CxPolicy[result] { + bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] + + object.get(bucket, "versioning", null) == null + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_objectstorage_bucket.%s", [bucket_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_objectstorage_bucket", bucket_name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "'versioning' attribute should be present and set to 'Enabled'", + "keyActualValue": "'versioning' attribute is missing, disabling versioning", + } +} + +# REGLA 2: El atributo 'versioning' existe pero no es 'Enabled'. +# Puede ser 'Disabled' o 'Suspended'. +CxPolicy[result] { + bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] + + object.get(bucket, "versioning", null) != null + bucket.versioning != "Enabled" + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_objectstorage_bucket.%s.versioning", [bucket_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_objectstorage_bucket", bucket_name, "versioning"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'versioning' attribute should be 'Enabled'", + "keyActualValue": sprintf("'versioning' attribute is '%s'", [bucket.versioning]), + } } \ No newline at end of file From 4c560c331d6b04be7edd02df31afb456debdc123 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:42 +0100 Subject: [PATCH 701/900] fix(rego): add searchLine to oci_resource_created_in_root_compartment --- .../query.rego | 103 +++++++++--------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/query.rego b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/query.rego index f779d3edb59..4d7355c8cf7 100644 --- a/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/query.rego +++ b/assets/queries/terraform/oci/oci_resource_created_in_root_compartment/query.rego @@ -1,53 +1,54 @@ -package Cx - +package Cx + import data.generic.common as common_lib -import future.keywords.in - -auditable_resource_types := { - "oci_core_instance", - "oci_core_vcn", - "oci_core_subnet", - "oci_core_security_list", - "oci_core_route_table", - "oci_core_internet_gateway", - "oci_core_nat_gateway", - "oci_core_service_gateway", - "oci_objectstorage_bucket", - "oci_database_db_system", - "oci_containerengine_cluster", - "oci_functions_application", - "oci_kms_vault", - "oci_ons_notification_topic" -} - -is_root_compartment(compartment_id) { - contains(lower(compartment_id), "var.tenancy_ocid") -} -is_root_compartment(compartment_id) { - contains(lower(compartment_id), "tenancy") -} - -CxPolicy[result] { - doc := input.document[i] - - some resource_type - resources := doc.resource[resource_type] - - resource_type in auditable_resource_types - - some resource_name - resource := resources[resource_name] - - compartment_id := object.get(resource, "compartment_id", "") - compartment_id != "" - - is_root_compartment(compartment_id) - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.%s.%s.compartment_id", [resource_type, resource_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Resource '%s' should be created in a child compartment, not the root compartment", [resource_name]), - "keyActualValue": sprintf("Resource '%s' is created in the root compartment (tenancy)", [resource_name]), - } +import future.keywords.in + +auditable_resource_types := { + "oci_core_instance", + "oci_core_vcn", + "oci_core_subnet", + "oci_core_security_list", + "oci_core_route_table", + "oci_core_internet_gateway", + "oci_core_nat_gateway", + "oci_core_service_gateway", + "oci_objectstorage_bucket", + "oci_database_db_system", + "oci_containerengine_cluster", + "oci_functions_application", + "oci_kms_vault", + "oci_ons_notification_topic" +} + +is_root_compartment(compartment_id) { + contains(lower(compartment_id), "var.tenancy_ocid") +} +is_root_compartment(compartment_id) { + contains(lower(compartment_id), "tenancy") +} + +CxPolicy[result] { + doc := input.document[i] + + some resource_type + resources := doc.resource[resource_type] + + resource_type in auditable_resource_types + + some resource_name + resource := resources[resource_name] + + compartment_id := object.get(resource, "compartment_id", "") + compartment_id != "" + + is_root_compartment(compartment_id) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.%s.%s.compartment_id", [resource_type, resource_name]), + "searchLine": common_lib.build_search_line(["resource", resource_type, resource_name, "compartment_id"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": sprintf("Resource '%s' should be created in a child compartment, not the root compartment", [resource_name]), + "keyActualValue": sprintf("Resource '%s' is created in the root compartment (tenancy)", [resource_name]), + } } \ No newline at end of file From 213a81b5c97e5e33e7c5d6dd7996f9f82be49e65 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:43 +0100 Subject: [PATCH 702/900] fix(rego): add searchLine to oci_storage_admin_no_delete_manual --- .../query.rego | 59 ++++++++++--------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/query.rego b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/query.rego index 429152d2fe1..dc8d0167c53 100644 --- a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/query.rego +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/query.rego @@ -1,29 +1,32 @@ -package Cx - -storage_families := { - "object-family", - "volume-family", - "file-family", - "autonomous-database-family" -} - -CxPolicy[result] { - doc := input.document[i] - policy := doc.resource.oci_identity_policy[name] - - statement := policy.statements[_] - statement_lower := lower(statement) - - regex.match("(?i)\\bmanage\\b", statement) - - family := storage_families[_] - contains(statement_lower, family) - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_identity_policy.%s.statements", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": sprintf("Statement granting 'manage' on '%s' should ideally exclude DELETE permissions via 'where request.permission != DELETE'", [family]), - "keyActualValue": sprintf("Statement grants full 'manage' access (including DELETE) on '%s': '%s'", [family, statement]), - } +package Cx + +import data.generic.common as common_lib + +storage_families := { + "object-family", + "volume-family", + "file-family", + "autonomous-database-family" +} + +CxPolicy[result] { + doc := input.document[i] + policy := doc.resource.oci_identity_policy[name] + + statement := policy.statements[_] + statement_lower := lower(statement) + + regex.match("(?i)\\bmanage\\b", statement) + + family := storage_families[_] + contains(statement_lower, family) + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_identity_policy.%s.statements", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_identity_policy", name, "statements"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": sprintf("Statement granting 'manage' on '%s' should ideally exclude DELETE permissions via 'where request.permission != DELETE'", [family]), + "keyActualValue": sprintf("Statement grants full 'manage' access (including DELETE) on '%s': '%s'", [family, statement]), + } } \ No newline at end of file From 953b393cc05ad40f6e466dae8d133b22995791ae Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 21:34:44 +0100 Subject: [PATCH 703/900] fix(rego): add searchLine to oci_subnet_flow_logging_disabled --- .../query.rego | 150 +++++++++--------- 1 file changed, 78 insertions(+), 72 deletions(-) diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/query.rego b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/query.rego index cdce921cd2f..05e4b099a33 100644 --- a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/query.rego +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/query.rego @@ -1,73 +1,79 @@ -package Cx - -# REGLA 1: No existe ningún log asociado a la subred (Missing) -CxPolicy[result] { - doc := input.document[i] - _ := doc.resource.oci_core_subnet[subnet_name] - - associated_logs := [l | - l := input.document[_].resource.oci_logging_log[_] - contains(l.configuration.source.resource, subnet_name) - ] - count(associated_logs) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_core_subnet.%s", [subnet_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "Subnet to have an associated VCN flow log", - "keyActualValue": "Subnet does not have an associated VCN flow log", - } -} - -# REGLA 2: Un log de flujo está deshabilitado -CxPolicy[result] { - doc := input.document[i] - log := doc.resource.oci_logging_log[log_name] - - log.log_type == "SERVICE" - object.get(log.configuration.source, "service", "") == "flowlogs" - log.is_enabled == false - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_logging_log.%s.is_enabled", [log_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'is_enabled' should be 'true'", - "keyActualValue": "'is_enabled' is 'false'", - } -} - -# REGLA 3: Un log de flujo tiene el tipo incorrecto -CxPolicy[result] { - doc := input.document[i] - log := doc.resource.oci_logging_log[log_name] - - object.get(log.configuration.source, "service", "") == "flowlogs" - log.log_type != "SERVICE" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_logging_log.%s.log_type", [log_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'log_type' should be 'SERVICE'", - "keyActualValue": sprintf("'log_type' is '%s'", [log.log_type]), - } -} - -# REGLA 4: Un log de flujo tiene el servicio incorrecto -CxPolicy[result] { - doc := input.document[i] - log := doc.resource.oci_logging_log[log_name] - - log.log_type == "SERVICE" - object.get(log.configuration.source, "service", "") != "flowlogs" - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_logging_log.%s.configuration.source.service", [log_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'service' should be 'flowlogs'", - "keyActualValue": sprintf("'service' is '%s'", [object.get(log.configuration.source, "service", "undefined")]), - } +package Cx + +import data.generic.common as common_lib + +# REGLA 1: No existe ningún log asociado a la subred (Missing) +CxPolicy[result] { + doc := input.document[i] + _ := doc.resource.oci_core_subnet[subnet_name] + + associated_logs := [l | + l := input.document[_].resource.oci_logging_log[_] + contains(l.configuration.source.resource, subnet_name) + ] + count(associated_logs) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_core_subnet.%s", [subnet_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_core_subnet", subnet_name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "Subnet to have an associated VCN flow log", + "keyActualValue": "Subnet does not have an associated VCN flow log", + } +} + +# REGLA 2: Un log de flujo está deshabilitado +CxPolicy[result] { + doc := input.document[i] + log := doc.resource.oci_logging_log[log_name] + + log.log_type == "SERVICE" + object.get(log.configuration.source, "service", "") == "flowlogs" + log.is_enabled == false + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_logging_log.%s.is_enabled", [log_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_logging_log", log_name, "is_enabled"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be 'true'", + "keyActualValue": "'is_enabled' is 'false'", + } +} + +# REGLA 3: Un log de flujo tiene el tipo incorrecto +CxPolicy[result] { + doc := input.document[i] + log := doc.resource.oci_logging_log[log_name] + + object.get(log.configuration.source, "service", "") == "flowlogs" + log.log_type != "SERVICE" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_logging_log.%s.log_type", [log_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_logging_log", log_name, "log_type"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'log_type' should be 'SERVICE'", + "keyActualValue": sprintf("'log_type' is '%s'", [log.log_type]), + } +} + +# REGLA 4: Un log de flujo tiene el servicio incorrecto +CxPolicy[result] { + doc := input.document[i] + log := doc.resource.oci_logging_log[log_name] + + log.log_type == "SERVICE" + object.get(log.configuration.source, "service", "") != "flowlogs" + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_logging_log.%s.configuration.source.service", [log_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_logging_log", log_name, "configuration", "source", "service"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'service' should be 'flowlogs'", + "keyActualValue": sprintf("'service' is '%s'", [object.get(log.configuration.source, "service", "undefined")]), + } } \ No newline at end of file From 489d0b1ca8bcea3c3e7ac8664caa41d2bbcae7f3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:08:50 +0100 Subject: [PATCH 704/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive2.tf index 6078908f9d1..4e777bb67b8 100644 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive2.tf +++ b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive2.tf @@ -1,13 +1,13 @@ -resource "azurerm_windows_web_app" "fail_incomplete_logs" { - name = "app-fail-2" - resource_group_name = "rg" - location = "West Europe" - service_plan_id = "plan-id" - - logs { - application_logs { - file_system_level = "Information" - } - # Falta http_logs - } +resource "azurerm_windows_web_app" "fail_incomplete_logs" { + name = "app-fail-2" + resource_group_name = "rg" + location = "West Europe" + service_plan_id = "plan-id" + + logs { + application_logs { + file_system_level = "Information" + } + # Missing http_logs + } } \ No newline at end of file From 5d65e3a37f1787949fc64e8d3ca9e4ee8eda6478 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:08:52 +0100 Subject: [PATCH 705/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive1.tf index b59e9f3d5a6..9be26f59a56 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive1.tf +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive1.tf @@ -1,8 +1,8 @@ -resource "azurerm_data_protection_backup_vault" "fail_missing" { - name = "vault-missing-crr" - resource_group_name = "rg-test" - location = "West Europe" - datastore_type = "VaultStore" - redundancy = "GeoRedundant" - # FALLO: Falta cross_region_restore_enabled +resource "azurerm_data_protection_backup_vault" "fail_missing" { + name = "vault-missing-crr" + resource_group_name = "rg-test" + location = "West Europe" + datastore_type = "VaultStore" + redundancy = "GeoRedundant" + # FAIL: Missing cross_region_restore_enabled } \ No newline at end of file From aebeaf29fd5b2629a49ed2a286877ccc623b65ff Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:08:55 +0100 Subject: [PATCH 706/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive1.tf index f058b9766a1..2db240d4874 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive1.tf +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive1.tf @@ -1,8 +1,8 @@ -resource "azurerm_data_protection_backup_vault" "fail" { - name = "vault-no-identity" - resource_group_name = "rg" - location = "West Europe" - datastore_type = "VaultStore" - redundancy = "LocallyRedundant" - # FALLO: No tiene bloque identity +resource "azurerm_data_protection_backup_vault" "fail" { + name = "vault-no-identity" + resource_group_name = "rg" + location = "West Europe" + datastore_type = "VaultStore" + redundancy = "LocallyRedundant" + # FAIL: No tiene bloque identity } \ No newline at end of file From 92a2b3335fdb0f4b65214ce3873549913c848a37 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:09:34 +0100 Subject: [PATCH 707/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive2.tf index 7c2838bfa7d..00f606b3c99 100644 --- a/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive2.tf +++ b/assets/queries/terraform/azure/azure_storage_blob_logging_disabled/test/positive2.tf @@ -1,6 +1,6 @@ -resource "azurerm_monitor_diagnostic_setting" "fail_no_logs" { - name = "empty-diag" - target_resource_id = "${azurerm_storage_account.example.id}/blobServices/default" - storage_account_id = "id" - # enabled_log bloque ausente +resource "azurerm_monitor_diagnostic_setting" "fail_no_logs" { + name = "empty-diag" + target_resource_id = "${azurerm_storage_account.example.id}/blobServices/default" + storage_account_id = "id" + # enabled_log bloque missing } \ No newline at end of file From dbf512f394bc0fc3912ab752a5c85b2bb3e7756b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:09:40 +0100 Subject: [PATCH 708/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive1.tf index aa4a19e1192..f8e34a8aeb5 100644 --- a/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive1.tf +++ b/assets/queries/terraform/azure/azure_storage_queue_logging_disabled/test/positive1.tf @@ -1,11 +1,11 @@ -resource "azurerm_storage_account" "fail_1" { - name = "stfail1" - resource_group_name = "rg" - location = "West Europe" - account_tier = "Standard" - account_replication_type = "LRS" - - queue_properties { - # Falta bloque logging - } +resource "azurerm_storage_account" "fail_1" { + name = "stfail1" + resource_group_name = "rg" + location = "West Europe" + account_tier = "Standard" + account_replication_type = "LRS" + + queue_properties { + # Missing bloque logging + } } \ No newline at end of file From 109f23cafe80c319dbf1ab448b27f7cb7bc6d826 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:14:41 +0100 Subject: [PATCH 709/900] chore: translate Spanish comments to English in positive2.tf --- .../gcp/gcp_access_approval_disabled/test/positive2.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive2.tf b/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive2.tf index 6e9ddf40f21..7a9af635d39 100644 --- a/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive2.tf +++ b/assets/queries/terraform/gcp/gcp_access_approval_disabled/test/positive2.tf @@ -1,4 +1,4 @@ -resource "google_access_approval_project_settings" "empty_settings" { - project_id = "some-project-id" - # FALLO: No tiene enrolled_services +resource "google_access_approval_project_settings" "empty_settings" { + project_id = "some-project-id" + # FAIL: No tiene enrolled_services } \ No newline at end of file From c5cb85956fffb5178de03f5b7edfb4c9c0dcacd7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:14:44 +0100 Subject: [PATCH 710/900] chore: translate Spanish comments to English in negative1.tf --- .../test/negative1.tf | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/negative1.tf b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/negative1.tf index 46aac8df6af..c15a1af37d4 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/negative1.tf +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/negative1.tf @@ -1,15 +1,15 @@ -resource "google_apikeys_key" "key_fully_secure" { - name = "fully-secure-key" - display_name = "Compliant Key" - - restrictions { - browser_key_restrictions { - allowed_referrers = ["https://example.com/*"] - } - - # CORRECTO: Acceso limitado a servicios específicos - api_targets { - service = "translate.googleapis.com" - } - } +resource "google_apikeys_key" "key_fully_secure" { + name = "fully-secure-key" + display_name = "Compliant Key" + + restrictions { + browser_key_restrictions { + allowed_referrers = ["https://example.com/*"] + } + + # PASS: Acceso limitado a servicios específicos + api_targets { + service = "translate.googleapis.com" + } + } } \ No newline at end of file From 5dac325819a713d5127431a952210a7126092367 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:14:46 +0100 Subject: [PATCH 711/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive2.tf b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive2.tf index 23ab9600179..4ad804ebc15 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive2.tf +++ b/assets/queries/terraform/gcp/gcp_api_key_api_targets_missing/test/positive2.tf @@ -1,11 +1,11 @@ -resource "google_apikeys_key" "key_no_targets" { - name = "partial-restricted-key" - display_name = "Key without API targets" - - restrictions { - server_key_restrictions { - allowed_ips = ["1.2.3.4"] - } - # FALLO: Falta el bloque api_targets - } +resource "google_apikeys_key" "key_no_targets" { + name = "partial-restricted-key" + display_name = "Key without API targets" + + restrictions { + server_key_restrictions { + allowed_ips = ["1.2.3.4"] + } + # FAIL: Missing The block api_targets + } } \ No newline at end of file From 0ba03fbcf70c417b7166155c5c512af94ba3b0f0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:14:48 +0100 Subject: [PATCH 712/900] chore: translate Spanish comments to English in query.rego --- .../terraform/gcp/gcp_api_key_restrictions_manual/query.rego | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego index 812040427f7..d0bcfa9e07c 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/query.rego @@ -3,7 +3,7 @@ package Cx import data.generic.common as common_lib import data.generic.terraform as tf_lib -# CASO 1: No hay restricciones definidas. +# CASE 1: No hay restricciones definidas. CxPolicy[result] { doc := input.document[i] key := doc.resource.google_apikeys_key[name] @@ -22,7 +22,7 @@ CxPolicy[result] { } } -# CASO 2: Hay restricciones definidas. +# CASE 2: Hay restricciones definidas. CxPolicy[result] { doc := input.document[i] key := doc.resource.google_apikeys_key[name] From 0e4070bdcc779137a8fd2532715cb7193b4669fa Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:14:50 +0100 Subject: [PATCH 713/900] chore: translate Spanish comments to English in positive1.tf --- .../gcp_api_key_restrictions_manual/test/positive1.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive1.tf b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive1.tf index 6a744bca5ef..cb327abca07 100644 --- a/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive1.tf +++ b/assets/queries/terraform/gcp/gcp_api_key_restrictions_manual/test/positive1.tf @@ -1,6 +1,6 @@ -resource "google_apikeys_key" "key_public" { - name = "public-key" - display_name = "Public Key" - project = "my-project" - # FALLO: No tiene bloque restrictions +resource "google_apikeys_key" "key_public" { + name = "public-key" + display_name = "Public Key" + project = "my-project" + # FAIL: No tiene bloque restrictions } \ No newline at end of file From 189b7679f2e9d3cf20c28e60f9f8b2347a265b5d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:14:53 +0100 Subject: [PATCH 714/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive1.tf b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive1.tf index 9e6e7822418..eef70148e59 100644 --- a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive1.tf +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive1.tf @@ -1,11 +1,11 @@ -resource "google_app_engine_standard_app_version" "app_insecure" { - service = "default" - version_id = "v1" - runtime = "python39" - - handlers { - url_regex = "/.*" - # FALLO: security_level no es SECURE_ALWAYS - security_level = "SECURE_OPTIONAL" - } +resource "google_app_engine_standard_app_version" "app_insecure" { + service = "default" + version_id = "v1" + runtime = "python39" + + handlers { + url_regex = "/.*" + # FAIL: security_level no es SECURE_ALWAYS + security_level = "SECURE_OPTIONAL" + } } \ No newline at end of file From ab0df21b25a04b9d5b362f8b1011704f8a745fde Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:14:55 +0100 Subject: [PATCH 715/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive2.tf b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive2.tf index 7ef1af37bdb..3e87e494cba 100644 --- a/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive2.tf +++ b/assets/queries/terraform/gcp/gcp_app_engine_https_enforcement_manual/test/positive2.tf @@ -1,6 +1,6 @@ -resource "google_app_engine_standard_app_version" "app_no_handlers" { - service = "backend" - version_id = "v1" - runtime = "go119" - # FALLO: Falta el bloque handlers, requiere revisión de app.yaml +resource "google_app_engine_standard_app_version" "app_no_handlers" { + service = "backend" + version_id = "v1" + runtime = "go119" + # FAIL: Missing The block handlers, requiere revisión de app.yaml } \ No newline at end of file From 98caec11260be4b2cedcbcc398546e5e82a9c766 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:15:00 +0100 Subject: [PATCH 716/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive1.tf index ee0134114dc..82a8af9ec26 100644 --- a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive1.tf +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive1.tf @@ -1,9 +1,9 @@ -resource "google_container_cluster" "fail_cluster" { - name = "insecure-cluster" - location = "us-central1" - - node_config { - machine_type = "e2-medium" - # FALLO: Falta service_account - } +resource "google_container_cluster" "fail_cluster" { + name = "insecure-cluster" + location = "us-central1" + + node_config { + machine_type = "e2-medium" + # FAIL: Missing service_account + } } \ No newline at end of file From aced76af02b77bd62e553ff194a4cf8c0ff1c8dc Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:15:01 +0100 Subject: [PATCH 717/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive2.tf index f7a9977968e..79ed1af857b 100644 --- a/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive2.tf +++ b/assets/queries/terraform/gcp/gcp_gke_default_service_account_used/test/positive2.tf @@ -1,9 +1,9 @@ -resource "google_container_node_pool" "fail_pool" { - name = "insecure-pool" - cluster = "some-cluster" - - node_config { - # FALLO: Falta service_account - preemptible = true - } +resource "google_container_node_pool" "fail_pool" { + name = "insecure-pool" + cluster = "some-cluster" + + node_config { + # FAIL: Missing service_account + preemptible = true + } } \ No newline at end of file From 1feec070069590d4f11bd9c4ccba7bba28d5719c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:15:04 +0100 Subject: [PATCH 718/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive1.tf index 28c1bac2b70..6e9f0695dfa 100644 --- a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive1.tf +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive1.tf @@ -1,9 +1,9 @@ -resource "google_container_cluster" "fail_cluster_no_block" { - name = "cluster-missing-metadata-config" - location = "us-central1" - - node_config { - machine_type = "e2-medium" - # FALLO: No existe workload_metadata_config - } +resource "google_container_cluster" "fail_cluster_no_block" { + name = "cluster-missing-metadata-config" + location = "us-central1" + + node_config { + machine_type = "e2-medium" + # FAIL: Does not exist workload_metadata_config + } } \ No newline at end of file From 25ff9734b6ca1d09b7960b45f338aced023411c4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:15:06 +0100 Subject: [PATCH 719/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive2.tf index 8fd70a39d23..176e5b080a2 100644 --- a/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive2.tf +++ b/assets/queries/terraform/gcp/gcp_gke_metadata_server_disabled/test/positive2.tf @@ -1,9 +1,9 @@ -resource "google_container_node_pool" "fail_pool_no_block" { - name = "pool-missing-metadata-config" - cluster = "my-cluster" - - node_config { - preemptible = true - # FALLO: No existe workload_metadata_config - } +resource "google_container_node_pool" "fail_pool_no_block" { + name = "pool-missing-metadata-config" + cluster = "my-cluster" + + node_config { + preemptible = true + # FAIL: Does not exist workload_metadata_config + } } \ No newline at end of file From 48a5a00a512f85dfee66d5fcf8a326eaa866291b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:15:10 +0100 Subject: [PATCH 720/900] chore: translate Spanish comments to English in positive1.tf --- .../gcp_gke_sandbox_disabled/test/positive1.tf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive1.tf index b8f9bd1346a..25e54824aec 100644 --- a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive1.tf +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive1.tf @@ -1,9 +1,9 @@ -resource "google_container_cluster" "fail_cluster_no_sandbox" { - name = "cluster-fail" - location = "us-central1" - - node_config { - machine_type = "e2-medium" - # FALLO: Falta sandbox_config - } +resource "google_container_cluster" "fail_cluster_no_sandbox" { + name = "cluster-fail" + location = "us-central1" + + node_config { + machine_type = "e2-medium" + # FAIL: Missing sandbox_config + } } \ No newline at end of file From 9faa21dfc220a1e6d9b71d0397870b9a9459c0f1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:15:12 +0100 Subject: [PATCH 721/900] chore: translate Spanish comments to English in positive2.tf --- .../gcp_gke_sandbox_disabled/test/positive2.tf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive2.tf b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive2.tf index 43a0a1006c9..9569727e33d 100644 --- a/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive2.tf +++ b/assets/queries/terraform/gcp/gcp_gke_sandbox_disabled/test/positive2.tf @@ -1,9 +1,9 @@ -resource "google_container_node_pool" "fail_pool_no_sandbox" { - name = "pool-fail" - cluster = "my-cluster" - - node_config { - machine_type = "e2-medium" - # FALLO: Falta sandbox_config - } +resource "google_container_node_pool" "fail_pool_no_sandbox" { + name = "pool-fail" + cluster = "my-cluster" + + node_config { + machine_type = "e2-medium" + # FAIL: Missing sandbox_config + } } \ No newline at end of file From ae3080e62345abb1940b87259435a4548090d1fd Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:15:15 +0100 Subject: [PATCH 722/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive1.tf b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive1.tf index ea4cefc36b6..cf8323e01d6 100644 --- a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive1.tf +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive1.tf @@ -1,5 +1,5 @@ -resource "google_container_cluster" "fail_missing_block" { - name = "no-encryption-block" - location = "us-central1" - # FALLO: database_encryption no existe +resource "google_container_cluster" "fail_missing_block" { + name = "no-encryption-block" + location = "us-central1" + # FAIL: database_encryption Does not exist } \ No newline at end of file From c0905db9a8407a986f3ad3a3753ec2dc682edf4c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:15:18 +0100 Subject: [PATCH 723/900] chore: translate Spanish comments to English in positive3.tf --- .../test/positive3.tf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive3.tf b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive3.tf index aa06e7a3f8d..bea1afe8339 100644 --- a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive3.tf +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/test/positive3.tf @@ -1,8 +1,8 @@ -resource "google_container_cluster" "fail_missing_key" { - name = "encrypted-no-key" - - # FALLO: Falta key_name - database_encryption { - state = "ENCRYPTED" - } +resource "google_container_cluster" "fail_missing_key" { + name = "encrypted-no-key" + + # FAIL: Missing key_name + database_encryption { + state = "ENCRYPTED" + } } \ No newline at end of file From a6242ca3f6b212126927e457b76d2175e8d378e5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:15:19 +0100 Subject: [PATCH 724/900] chore: translate Spanish comments to English in query.rego --- .../gcp/gcp_http_load_balancer_logging_disabled/query.rego | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego index ce9034bfa68..1cd6ba774ef 100644 --- a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/query.rego @@ -3,7 +3,7 @@ package Cx import data.generic.common as common_lib import data.generic.terraform as tf_lib -# REGLA 1: Bloque 'log_config' ausente. +# RULE 1: Bloque 'log_config' missing. CxPolicy[result] { doc := input.document[i] bs := doc.resource.google_compute_backend_service[name] @@ -22,7 +22,7 @@ CxPolicy[result] { } } -# REGLA 2: Bloque 'log_config' existe pero 'enable' es false. +# RULE 2: Bloque 'log_config' Exists but 'enable' es false. CxPolicy[result] { doc := input.document[i] bs := doc.resource.google_compute_backend_service[name] From f0b2d5e81283836e96c1f11638fbd129b6f451cb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:15:21 +0100 Subject: [PATCH 725/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive1.tf b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive1.tf index 0180ab2193a..a6b59c65cd7 100644 --- a/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive1.tf +++ b/assets/queries/terraform/gcp/gcp_http_load_balancer_logging_disabled/test/positive1.tf @@ -1,5 +1,5 @@ -resource "google_compute_backend_service" "fail_missing_log" { - name = "backend-no-logs" - protocol = "HTTP" - # FALLO: No tiene bloque log_config +resource "google_compute_backend_service" "fail_missing_log" { + name = "backend-no-logs" + protocol = "HTTP" + # FAIL: No tiene bloque log_config } \ No newline at end of file From dc113a154a5191fde8057a847f7dd1c9f8528abc Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:15:23 +0100 Subject: [PATCH 726/900] chore: translate Spanish comments to English in query.rego --- .../gcp/gcp_iap_backend_service_disabled/query.rego | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego index 0de21c99587..6bd226bd2b4 100644 --- a/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_iap_backend_service_disabled/query.rego @@ -3,7 +3,7 @@ package Cx import data.generic.common as common_lib import data.generic.terraform as tf_lib -# REGLA 1: El bloque 'iap' está ausente en google_compute_backend_service. +# RULE 1: The block 'iap' is missing en google_compute_backend_service. CxPolicy[result] { doc := input.document[i] bs := doc.resource.google_compute_backend_service[name] @@ -22,7 +22,7 @@ CxPolicy[result] { } } -# REGLA 2: El bloque 'iap' existe pero falta 'oauth2_client_id'. +# RULE 2: The block 'iap' Exists but Missing 'oauth2_client_id'. CxPolicy[result] { doc := input.document[i] bs := doc.resource.google_compute_backend_service[name] @@ -42,7 +42,7 @@ CxPolicy[result] { } } -# REGLA 3: El bloque 'iap' existe pero falta 'oauth2_client_secret'. +# RULE 3: The block 'iap' Exists but Missing 'oauth2_client_secret'. CxPolicy[result] { doc := input.document[i] bs := doc.resource.google_compute_backend_service[name] From 4a8f3d08c8e294354c14ed7f52cab00aefaa38d4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:03 +0100 Subject: [PATCH 727/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego index 3104c2dfd3c..43755080a35 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego @@ -1,41 +1,41 @@ -package Cx - -# REGLA 1: No existe ningún recurso 'ibm_resource_instance' para 'activity-tracker'. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.ibm - - all_activity_trackers := [tracker | - tracker := input.document[_].resource.ibm_resource_instance[_] - tracker.service == "activity-tracker" - ] - - count(all_activity_trackers) == 0 - - result := { - "documentId": doc.id, +package Cx + +# RULE 1: Does not exist ningún resource 'ibm_resource_instance' para 'activity-tracker'. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.ibm + + all_activity_trackers := [tracker | + tracker := input.document[_].resource.ibm_resource_instance[_] + tracker.service == "activity-tracker" + ] + + count(all_activity_trackers) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.ibm", - "searchLine": common_lib.build_search_line(["provider", "ibm"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "An 'ibm_resource_instance' with service='activity-tracker' should exist", - "keyActualValue": "No 'ibm_resource_instance' for service 'activity-tracker' was found", - } -} - -# REGLA 2: Una instancia de 'activity-tracker' está en una región incorrecta para eventos globales. -CxPolicy[result] { - global_event_regions := {"eu-de", "eu-gb", "us-south", "au-syd"} - - tracker := input.document[i].resource.ibm_resource_instance[tracker_name] - tracker.service == "activity-tracker" - - not global_event_regions[tracker.location] - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.ibm_resource_instance.%s.location", [tracker_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "Activity Tracker 'location' should be a global event region (e.g., 'eu-de', 'us-south')", - "keyActualValue": sprintf("Activity Tracker 'location' is '%s', which is not a global event region", [tracker.location]), - } + "searchLine": common_lib.build_search_line(["provider", "ibm"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'ibm_resource_instance' with service='activity-tracker' should exist", + "keyActualValue": "No 'ibm_resource_instance' for service 'activity-tracker' was found", + } +} + +# RULE 2: Una instancia de 'activity-tracker' está en una región incorrecta para events globales. +CxPolicy[result] { + global_event_regions := {"eu-de", "eu-gb", "us-south", "au-syd"} + + tracker := input.document[i].resource.ibm_resource_instance[tracker_name] + tracker.service == "activity-tracker" + + not global_event_regions[tracker.location] + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_resource_instance.%s.location", [tracker_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "Activity Tracker 'location' should be a global event region (e.g., 'eu-de', 'us-south')", + "keyActualValue": sprintf("Activity Tracker 'location' is '%s', which is not a global event region", [tracker.location]), + } } \ No newline at end of file From 8c02a0f807da8d79795a26e3dd9ac4d388444050 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:06 +0100 Subject: [PATCH 728/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 106 +++++++++--------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego index 566c736f2e2..fb8dfc6e424 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego @@ -1,55 +1,55 @@ -package Cx - -# REGLA 1: No existe ningún recurso 'ibm_resource_instance' para el servicio 'activity-tracker'. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.ibm - - all_activity_trackers := [tracker | - tracker := input.document[_].resource.ibm_resource_instance[_] - tracker.service == "activity-tracker" - ] - - count(all_activity_trackers) == 0 - - result := { - "documentId": doc.id, +package Cx + +# RULE 1: Does not exist ningún resource 'ibm_resource_instance' para el servicio 'activity-tracker'. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.ibm + + all_activity_trackers := [tracker | + tracker := input.document[_].resource.ibm_resource_instance[_] + tracker.service == "activity-tracker" + ] + + count(all_activity_trackers) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.ibm", - "searchLine": common_lib.build_search_line(["provider", "ibm"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "An 'ibm_resource_instance' with service='activity-tracker' should exist", - "keyActualValue": "No 'ibm_resource_instance' for service 'activity-tracker' was found", - } -} - -# REGLA 2: El atributo 'platform_logs' está ausente en la instancia de Activity Tracker. -CxPolicy[result] { - tracker := input.document[i].resource.ibm_resource_instance[tracker_name] - tracker.service == "activity-tracker" - - object.get(tracker, "platform_logs", null) == null - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.ibm_resource_instance.%s", [tracker_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'platform_logs' attribute should be present and set to 'true'", - "keyActualValue": "'platform_logs' attribute is missing and defaults to 'false'", - } -} - -# REGLA 3: El atributo 'platform_logs' está explícitamente configurado como 'false'. -CxPolicy[result] { - tracker := input.document[i].resource.ibm_resource_instance[tracker_name] - tracker.service == "activity-tracker" - - tracker.platform_logs == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.ibm_resource_instance.%s.platform_logs", [tracker_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'platform_logs' attribute should be 'true'", - "keyActualValue": "'platform_logs' attribute is 'false'", - } + "searchLine": common_lib.build_search_line(["provider", "ibm"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'ibm_resource_instance' with service='activity-tracker' should exist", + "keyActualValue": "No 'ibm_resource_instance' for service 'activity-tracker' was found", + } +} + +# RULE 2: The 'platform_logs' attribute is missing en la instancia de Activity Tracker. +CxPolicy[result] { + tracker := input.document[i].resource.ibm_resource_instance[tracker_name] + tracker.service == "activity-tracker" + + object.get(tracker, "platform_logs", null) == null + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_resource_instance.%s", [tracker_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'platform_logs' attribute should be present and set to 'true'", + "keyActualValue": "'platform_logs' attribute is missing and defaults to 'false'", + } +} + +# RULE 3: The attribute 'platform_logs' está explícitamente configurado como 'false'. +CxPolicy[result] { + tracker := input.document[i].resource.ibm_resource_instance[tracker_name] + tracker.service == "activity-tracker" + + tracker.platform_logs == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_resource_instance.%s.platform_logs", [tracker_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'platform_logs' attribute should be 'true'", + "keyActualValue": "'platform_logs' attribute is 'false'", + } } \ No newline at end of file From c0747af4bfac0cdd1fe926eb3d4b82e96d9ff970 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:09 +0100 Subject: [PATCH 729/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive2.tf b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive2.tf index 6094a5408a3..4bf73552723 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive2.tf +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive2.tf @@ -1,11 +1,11 @@ -provider "ibm" { - region = "eu-de" -} - -resource "ibm_resource_instance" "tracker_no_attr" { - name = "activity-tracker-missing" - service = "activity-tracker" - plan = "lite" - location = "eu-de" - # FALLO: Falta platform_logs +provider "ibm" { + region = "eu-de" +} + +resource "ibm_resource_instance" "tracker_no_attr" { + name = "activity-tracker-missing" + service = "activity-tracker" + plan = "lite" + location = "eu-de" + # FAIL: Missing platform_logs } \ No newline at end of file From c621dac6c503000d56658630c83f6ddd374e60fb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:10 +0100 Subject: [PATCH 730/900] chore: translate Spanish comments to English in positive3.tf --- .../test/positive3.tf | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive3.tf b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive3.tf index a0da5210e4a..3064b260dd5 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive3.tf +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/test/positive3.tf @@ -1,13 +1,13 @@ -provider "ibm" { - region = "eu-de" -} - -resource "ibm_resource_instance" "tracker_disabled" { - name = "activity-tracker-off" - service = "activity-tracker" - plan = "lite" - location = "eu-de" - - # FALLO: Deshabilitado explícitamente - platform_logs = false +provider "ibm" { + region = "eu-de" +} + +resource "ibm_resource_instance" "tracker_disabled" { + name = "activity-tracker-off" + service = "activity-tracker" + plan = "lite" + location = "eu-de" + + # FAIL: Deshabilitado explícitamente + platform_logs = false } \ No newline at end of file From ca25699a971894a17e3b455ee87ccbe98a789ddb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:12 +0100 Subject: [PATCH 731/900] chore: translate Spanish comments to English in query.rego --- .../ibm_certificate_manager_auto_renew_disabled/query.rego | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/query.rego b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/query.rego index 9999c9731df..04df8a67194 100644 --- a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.common as common_lib -# REGLA 1: El atributo 'auto_renew_enabled' está ausente en el certificado. +# RULE 1: The 'auto_renew_enabled' attribute is missing en el certificado. CxPolicy[result] { doc := input.document[i] certificate := doc.resource.ibm_cm_certificate[cert_name] @@ -19,7 +19,7 @@ CxPolicy[result] { } } -# REGLA 2: El atributo 'auto_renew_enabled' está explícitamente configurado como 'false'. +# RULE 2: The attribute 'auto_renew_enabled' está explícitamente configurado como 'false'. CxPolicy[result] { doc := input.document[i] certificate := doc.resource.ibm_cm_certificate[cert_name] From f919ef9ae8ea9aabe8669668422d750e8aba6b56 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:14 +0100 Subject: [PATCH 732/900] chore: translate Spanish comments to English in negative1.tf --- .../test/negative1.tf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/negative1.tf b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/negative1.tf index e44ea543251..093011f11df 100644 --- a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/negative1.tf +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/negative1.tf @@ -1,8 +1,8 @@ -resource "ibm_cm_certificate" "cert_compliant" { - instance_id = "crn:v1:bluemix:public:cloudcerts:..." - name = "cert-compliant" - label = "secure" - - # CORRECTO - auto_renew_enabled = true +resource "ibm_cm_certificate" "cert_compliant" { + instance_id = "crn:v1:bluemix:public:cloudcerts:..." + name = "cert-compliant" + label = "secure" + + # PASS + auto_renew_enabled = true } \ No newline at end of file From e0d01ce0168e88f6e4db42b0192fda6d4c621032 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:15 +0100 Subject: [PATCH 733/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive1.tf b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive1.tf index 0c8ea62b35c..039efe5432c 100644 --- a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive1.tf +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive1.tf @@ -1,6 +1,6 @@ -resource "ibm_cm_certificate" "cert_missing_attr" { - instance_id = "crn:v1:bluemix:public:cloudcerts:..." - name = "cert-missing" - label = "test" - # FALLO: Falta auto_renew_enabled +resource "ibm_cm_certificate" "cert_missing_attr" { + instance_id = "crn:v1:bluemix:public:cloudcerts:..." + name = "cert-missing" + label = "test" + # FAIL: Missing auto_renew_enabled } \ No newline at end of file From 78aa4b071a6666c38f943a6f53b6b36033dee15e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:17 +0100 Subject: [PATCH 734/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive2.tf b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive2.tf index 569d61fc484..1518beba8a7 100644 --- a/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive2.tf +++ b/assets/queries/terraform/ibm/ibm_certificate_manager_auto_renew_disabled/test/positive2.tf @@ -1,8 +1,8 @@ -resource "ibm_cm_certificate" "cert_disabled" { - instance_id = "crn:v1:bluemix:public:cloudcerts:..." - name = "cert-disabled" - label = "test" - - # FALLO: Deshabilitado explícitamente - auto_renew_enabled = false +resource "ibm_cm_certificate" "cert_disabled" { + instance_id = "crn:v1:bluemix:public:cloudcerts:..." + name = "cert-disabled" + label = "test" + + # FAIL: Deshabilitado explícitamente + auto_renew_enabled = false } \ No newline at end of file From d24e34f3bebbce110d96b118dea9f8181077eea4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:18 +0100 Subject: [PATCH 735/900] chore: translate Spanish comments to English in query.rego --- .../terraform/ibm/ibm_cis_dns_not_proxied_manual/query.rego | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/query.rego b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/query.rego index 1932c75cf04..d144203fcab 100644 --- a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/query.rego +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.common as common_lib -# CASO 1: El atributo 'proxied' está explícitamente en false. +# CASE 1: The attribute 'proxied' está explícitamente en false. CxPolicy[result] { doc := input.document[i] record := doc.resource.ibm_cis_dns_record[name] @@ -19,7 +19,7 @@ CxPolicy[result] { } } -# CASO 2: El atributo 'proxied' falta (por defecto es false). +# CASE 2: The attribute 'proxied' Missing (por defecto es false). CxPolicy[result] { doc := input.document[i] record := doc.resource.ibm_cis_dns_record[name] From e6c4625f449ee4a1d915589ab078bc929f0157d4 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:20 +0100 Subject: [PATCH 736/900] chore: translate Spanish comments to English in negative1.tf --- .../test/negative1.tf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/negative1.tf index 25f0badd996..43bb8e92417 100644 --- a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/negative1.tf +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/negative1.tf @@ -1,10 +1,10 @@ -resource "ibm_cis_dns_record" "dns_record_secure" { - cis_id = "crn:v1:bluemix:public:internet-svcs:..." - domain_id = "example-id" - name = "www" - type = "A" - content = "1.2.3.4" - - # CORRECTO: Bajo el escudo de CIS - proxied = true +resource "ibm_cis_dns_record" "dns_record_secure" { + cis_id = "crn:v1:bluemix:public:internet-svcs:..." + domain_id = "example-id" + name = "www" + type = "A" + content = "1.2.3.4" + + # PASS: Bajo el escudo de CIS + proxied = true } \ No newline at end of file From a78d48c46a89f6b1aea2236d61f8de5f6be0c16e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:21 +0100 Subject: [PATCH 737/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive1.tf index 8509014995b..212f69b7952 100644 --- a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive1.tf +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive1.tf @@ -1,10 +1,10 @@ -resource "ibm_cis_dns_record" "dns_record_false" { - cis_id = "crn:v1:bluemix:public:internet-svcs:..." - domain_id = "example-id" - name = "test" - type = "A" - content = "192.168.1.1" - - # FALLO: Deshabilitado explícitamente - proxied = false +resource "ibm_cis_dns_record" "dns_record_false" { + cis_id = "crn:v1:bluemix:public:internet-svcs:..." + domain_id = "example-id" + name = "test" + type = "A" + content = "192.168.1.1" + + # FAIL: Deshabilitado explícitamente + proxied = false } \ No newline at end of file From 8e6ea0b8898872fa964e2e30519e54bf5149c555 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:23 +0100 Subject: [PATCH 738/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive2.tf b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive2.tf index de686df1b4c..9de55a90331 100644 --- a/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive2.tf +++ b/assets/queries/terraform/ibm/ibm_cis_dns_not_proxied_manual/test/positive2.tf @@ -1,8 +1,8 @@ -resource "ibm_cis_dns_record" "dns_record_missing" { - cis_id = "crn:v1:bluemix:public:internet-svcs:..." - domain_id = "example-id" - name = "test-missing" - type = "A" - content = "192.168.1.2" - # FALLO: Falta el atributo proxied +resource "ibm_cis_dns_record" "dns_record_missing" { + cis_id = "crn:v1:bluemix:public:internet-svcs:..." + domain_id = "example-id" + name = "test-missing" + type = "A" + content = "192.168.1.2" + # FAIL: Missing The attribute proxied } \ No newline at end of file From 1549e93d274d64ddbdac5ae9267faffbb5ae6589 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:24 +0100 Subject: [PATCH 739/900] chore: translate Spanish comments to English in query.rego --- .../terraform/ibm/ibm_cis_waf_enabled_manual/query.rego | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/query.rego b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/query.rego index 96e622b0c8c..937fc312224 100644 --- a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/query.rego +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.common as common_lib -# CASO 1: El atributo 'waf' existe pero tiene un valor incorrecto (ej. "off"). +# CASE 1: The attribute 'waf' Exists but tiene un valor incorrecto (ej. "off"). CxPolicy[result] { doc := input.document[i] settings := doc.resource.ibm_cis_domain_settings[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# CASO 2: El atributo 'waf' NO existe en el recurso (valor por defecto varía por plan, se requiere definición explícita). +# CASE 2: The attribute 'waf' Does not exist en el resource (valor por defecto varía por plan, se requiere definición explícita). CxPolicy[result] { doc := input.document[i] settings := doc.resource.ibm_cis_domain_settings[name] From 5994bcb2af7bb0328265756fece679e7ca3a1e7b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:26 +0100 Subject: [PATCH 740/900] chore: translate Spanish comments to English in negative1.tf --- .../ibm/ibm_cis_waf_enabled_manual/test/negative1.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/negative1.tf index 82413ddf80d..eb2779c7f58 100644 --- a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/negative1.tf +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/negative1.tf @@ -1,7 +1,7 @@ -resource "ibm_cis_domain_settings" "settings_secure" { - cis_id = "crn:v1:bluemix:public:internet-svcs:..." - domain_id = "example-id" - - # CORRECTO: WAF habilitado - waf = "on" +resource "ibm_cis_domain_settings" "settings_secure" { + cis_id = "crn:v1:bluemix:public:internet-svcs:..." + domain_id = "example-id" + + # PASS: WAF habilitado + waf = "on" } \ No newline at end of file From 54a994d25c46b7ea5a98cf8f90890fe8edb2807c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:28 +0100 Subject: [PATCH 741/900] chore: translate Spanish comments to English in positive1.tf --- .../ibm/ibm_cis_waf_enabled_manual/test/positive1.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive1.tf index 51146b79b6a..cdc74d69831 100644 --- a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive1.tf +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive1.tf @@ -1,7 +1,7 @@ -resource "ibm_cis_domain_settings" "settings_off" { - cis_id = "crn:v1:bluemix:public:internet-svcs:..." - domain_id = "example-id" - - # FALLO: WAF desactivado - waf = "off" +resource "ibm_cis_domain_settings" "settings_off" { + cis_id = "crn:v1:bluemix:public:internet-svcs:..." + domain_id = "example-id" + + # FAIL: WAF desactivado + waf = "off" } \ No newline at end of file From 4f3cceea2cfd8f787e753ff830711d67c2adba78 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:29 +0100 Subject: [PATCH 742/900] chore: translate Spanish comments to English in positive2.tf --- .../ibm/ibm_cis_waf_enabled_manual/test/positive2.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive2.tf b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive2.tf index 1f424d8f271..6ca054580ee 100644 --- a/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive2.tf +++ b/assets/queries/terraform/ibm/ibm_cis_waf_enabled_manual/test/positive2.tf @@ -1,6 +1,6 @@ -resource "ibm_cis_domain_settings" "settings_missing" { - cis_id = "crn:v1:bluemix:public:internet-svcs:..." - domain_id = "example-id" - # FALLO: Falta el atributo waf - ssl = "full" +resource "ibm_cis_domain_settings" "settings_missing" { + cis_id = "crn:v1:bluemix:public:internet-svcs:..." + domain_id = "example-id" + # FAIL: Missing The attribute waf + ssl = "full" } \ No newline at end of file From cdca1cc22a56061af6fd2629ff44515faa1df006 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:31 +0100 Subject: [PATCH 743/900] chore: translate Spanish comments to English in query.rego --- .../ibm/ibm_cloudant_cmk_encryption_manual/query.rego | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/query.rego b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/query.rego index 3fb8187aa10..1e145200c0c 100644 --- a/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/query.rego +++ b/assets/queries/terraform/ibm/ibm_cloudant_cmk_encryption_manual/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.common as common_lib -# CASO 1: El bloque 'parameters' está ausente. +# CASE 1: The block 'parameters' is missing. CxPolicy[result] { doc := input.document[i] resource := doc.resource.ibm_resource_instance[name] @@ -20,7 +20,7 @@ CxPolicy[result] { } } -# CASO 2: El bloque 'parameters' existe pero falta 'key_protect_key'. +# CASE 2: The block 'parameters' Exists but Missing 'key_protect_key'. CxPolicy[result] { doc := input.document[i] resource := doc.resource.ibm_resource_instance[name] From aa6cf40ad6606c08502c78717ffa1c29d4d4391e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:34 +0100 Subject: [PATCH 744/900] chore: translate Spanish comments to English in negative1.tf --- .../test/negative1.tf | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/negative1.tf b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/negative1.tf index 0d9ea9b13b7..e7e1f546581 100644 --- a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/negative1.tf +++ b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/negative1.tf @@ -1,15 +1,15 @@ -provider "ibm" { - region = "us-south" -} - -resource "ibm_container_cluster" "cluster_with_entitlement" { - name = "secure-cluster" - datacenter = "dal10" - machine_type = "b3c.4x16" - hardware = "shared" - public_vlan_id = "123" - private_vlan_id = "456" - - # CORRECTO: Se automatiza el secreto de descarga - entitlement = "my-entitlement-key-crn" +provider "ibm" { + region = "us-south" +} + +resource "ibm_container_cluster" "cluster_with_entitlement" { + name = "secure-cluster" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + public_vlan_id = "123" + private_vlan_id = "456" + + # PASS: Se automatiza el secreto de descarga + entitlement = "my-entitlement-key-crn" } \ No newline at end of file From 62b855c9d066346b290e8a52bb6813d9ac51de6a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:36 +0100 Subject: [PATCH 745/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive1.tf b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive1.tf index cf80ba4a204..de1b402967b 100644 --- a/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive1.tf +++ b/assets/queries/terraform/ibm/ibm_container_cluster_entitlement_check/test/positive1.tf @@ -1,13 +1,13 @@ -provider "ibm" { - region = "us-south" -} - -resource "ibm_container_cluster" "cluster_without_entitlement" { - name = "test-cluster" - datacenter = "dal10" - machine_type = "b3c.4x16" - hardware = "shared" - public_vlan_id = "123" - private_vlan_id = "456" - # FALLO: No se define 'entitlement' +provider "ibm" { + region = "us-south" +} + +resource "ibm_container_cluster" "cluster_without_entitlement" { + name = "test-cluster" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + public_vlan_id = "123" + private_vlan_id = "456" + # FAIL: No se define 'entitlement' } \ No newline at end of file From 2800fb865bf3dff367c97fb1f0d0102c41476af0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:38 +0100 Subject: [PATCH 746/900] chore: translate Spanish comments to English in negative1.tf --- .../test/negative1.tf | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/negative1.tf b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/negative1.tf index dc8b4fbc202..caacafa3fa9 100644 --- a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/negative1.tf +++ b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/negative1.tf @@ -1,18 +1,18 @@ -provider "ibm" { - region = "us-south" -} - -resource "ibm_container_cluster" "secure_cluster" { - name = "secure-setup" - datacenter = "dal10" - machine_type = "b3c.4x16" - hardware = "shared" - public_vlan_id = "123" - private_vlan_id = "456" -} - -# CORRECTO: Se define la notificación para el VA -resource "ibm_container_va_notification" "alerts" { - cluster_id = ibm_container_cluster.secure_cluster.id - email = "admin@example.com" +provider "ibm" { + region = "us-south" +} + +resource "ibm_container_cluster" "secure_cluster" { + name = "secure-setup" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + public_vlan_id = "123" + private_vlan_id = "456" +} + +# PASS: Se define la notificación para el VA +resource "ibm_container_va_notification" "alerts" { + cluster_id = ibm_container_cluster.secure_cluster.id + email = "admin@example.com" } \ No newline at end of file From 47f5d8ece943625e53b4b1142916921f71c27286 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:39 +0100 Subject: [PATCH 747/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive1.tf b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive1.tf index 5c53735bfa1..cf172e3a86f 100644 --- a/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive1.tf +++ b/assets/queries/terraform/ibm/ibm_container_registry_va_alerts_missing/test/positive1.tf @@ -1,13 +1,13 @@ -provider "ibm" { - region = "us-south" -} - -resource "ibm_container_cluster" "cluster_without_va" { - name = "vulnerable-setup" - datacenter = "dal10" - machine_type = "b3c.4x16" - hardware = "shared" - public_vlan_id = "123" - private_vlan_id = "456" - # FALLO: No existe un ibm_container_va_notification en el documento +provider "ibm" { + region = "us-south" +} + +resource "ibm_container_cluster" "cluster_without_va" { + name = "vulnerable-setup" + datacenter = "dal10" + machine_type = "b3c.4x16" + hardware = "shared" + public_vlan_id = "123" + private_vlan_id = "456" + # FAIL: Does not exist un ibm_container_va_notification en el documento } \ No newline at end of file From ca047c2f8c728d9c8ae5a51fe0b576f3aa428664 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:41 +0100 Subject: [PATCH 748/900] chore: translate Spanish comments to English in query.rego --- .../terraform/ibm/ibm_database_cmk_encryption_manual/query.rego | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/query.rego b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/query.rego index 3fcf44a5904..86be8b519b0 100644 --- a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/query.rego +++ b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.common as common_lib -# CASO 1: Base de datos sin 'key_protect_key'. +# CASE 1: Base de datos sin 'key_protect_key'. CxPolicy[result] { doc := input.document[i] db := doc.resource.ibm_database[name] From f9aaeb7cb19e52f1d16e38f81eb561a154e5764f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:42 +0100 Subject: [PATCH 749/900] chore: translate Spanish comments to English in negative1.tf --- .../test/negative1.tf | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/negative1.tf b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/negative1.tf index e180275711d..924676e68d7 100644 --- a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/negative1.tf +++ b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/negative1.tf @@ -1,13 +1,13 @@ -provider "ibm" { - region = "us-south" -} - -resource "ibm_database" "db_secure" { - name = "db-protected" - service = "databases-for-postgresql" - plan = "standard" - location = "us-south" - - # CORRECTO: Se define la clave de cifrado del cliente - key_protect_key = "crn:v1:bluemix:public:kms:us-south:a/test:test:key:test" +provider "ibm" { + region = "us-south" +} + +resource "ibm_database" "db_secure" { + name = "db-protected" + service = "databases-for-postgresql" + plan = "standard" + location = "us-south" + + # PASS: Se define la clave de cifrado del cliente + key_protect_key = "crn:v1:bluemix:public:kms:us-south:a/test:test:key:test" } \ No newline at end of file From 2c84275809167f51e81c56812a0957ad05233007 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:44 +0100 Subject: [PATCH 750/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive1.tf b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive1.tf index 0263c170bcf..c4cfe72e017 100644 --- a/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive1.tf +++ b/assets/queries/terraform/ibm/ibm_database_cmk_encryption_manual/test/positive1.tf @@ -1,11 +1,11 @@ -provider "ibm" { - region = "us-south" -} - -resource "ibm_database" "db_insecure" { - name = "db-standard" - service = "databases-for-mongodb" - plan = "standard" - location = "us-south" - # FALLO: Falta el atributo key_protect_key +provider "ibm" { + region = "us-south" +} + +resource "ibm_database" "db_insecure" { + name = "db-standard" + service = "databases-for-mongodb" + plan = "standard" + location = "us-south" + # FAIL: Missing The attribute key_protect_key } \ No newline at end of file From 2f725c412edb37725f6dc9b1d00e81dd6ea2fbaa Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:46 +0100 Subject: [PATCH 751/900] chore: translate Spanish comments to English in query.rego --- .../ibm/ibm_iam_account_ip_restrictions_manual/query.rego | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/query.rego b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/query.rego index 9973f4405d6..912b2f40a06 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/query.rego +++ b/assets/queries/terraform/ibm/ibm_iam_account_ip_restrictions_manual/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.common as common_lib -# CASO 1: Restricciones de IP no configuradas (Atributo ausente). +# CASE 1: Restricciones de IP no configuradas (Atributo missing). CxPolicy[result] { doc := input.document[i] settings := doc.resource.ibm_iam_account_settings[name] @@ -19,7 +19,7 @@ CxPolicy[result] { } } -# CASO 2: Restricciones definidas pero lista vacía. +# CASE 2: Restricciones definidas but lista vacía. CxPolicy[result] { doc := input.document[i] settings := doc.resource.ibm_iam_account_settings[name] From 6e7056d259eff0df9962754aa032e61fb9ac56f0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:49 +0100 Subject: [PATCH 752/900] chore: translate Spanish comments to English in query.rego --- .../ibm_iam_account_mfa_disabled/query.rego | 98 +++++++++---------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego index e1cfb636772..04e5d11064f 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego @@ -1,51 +1,51 @@ -package Cx - -# REGLA 1: El recurso 'ibm_iam_account_settings' no existe en la configuración. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.ibm - - all_iam_settings := [settings | - settings := input.document[_].resource.ibm_iam_account_settings[_] - ] - - count(all_iam_settings) == 0 - - result := { - "documentId": doc.id, +package Cx + +# RULE 1: El resource 'ibm_iam_account_settings' Does not exist en la configuración. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.ibm + + all_iam_settings := [settings | + settings := input.document[_].resource.ibm_iam_account_settings[_] + ] + + count(all_iam_settings) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.ibm", - "searchLine": common_lib.build_search_line(["provider", "ibm"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "Resource 'ibm_iam_account_settings' should exist to enforce MFA", - "keyActualValue": "Resource 'ibm_iam_account_settings' is missing in this IBM configuration", - } -} - -# REGLA 2: El atributo 'mfa' está ausente dentro del recurso. -CxPolicy[result] { - settings := input.document[i].resource.ibm_iam_account_settings[settings_name] - object.get(settings, "mfa", null) == null - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.ibm_iam_account_settings.%s", [settings_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'mfa' attribute should be present and set to 'LEVEL2' or 'LEVEL3'", - "keyActualValue": "'mfa' attribute is missing", - } -} - -# REGLA 3: El atributo 'mfa' tiene un valor inseguro ('NONE' o 'LEVEL1'). -CxPolicy[result] { - settings := input.document[i].resource.ibm_iam_account_settings[settings_name] - insecure_mfa_levels := {"NONE", "LEVEL1"} - insecure_mfa_levels[settings.mfa] - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.ibm_iam_account_settings.%s.mfa", [settings_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'mfa' attribute should be 'LEVEL2' or 'LEVEL3'", - "keyActualValue": sprintf("'mfa' attribute is set to '%s'", [settings.mfa]), - } + "searchLine": common_lib.build_search_line(["provider", "ibm"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "Resource 'ibm_iam_account_settings' should exist to enforce MFA", + "keyActualValue": "Resource 'ibm_iam_account_settings' is missing in this IBM configuration", + } +} + +# RULE 2: The 'mfa' attribute is missing within the resource. +CxPolicy[result] { + settings := input.document[i].resource.ibm_iam_account_settings[settings_name] + object.get(settings, "mfa", null) == null + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_iam_account_settings.%s", [settings_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'mfa' attribute should be present and set to 'LEVEL2' or 'LEVEL3'", + "keyActualValue": "'mfa' attribute is missing", + } +} + +# RULE 3: The attribute 'mfa' tiene un valor inseguro ('NONE' o 'LEVEL1'). +CxPolicy[result] { + settings := input.document[i].resource.ibm_iam_account_settings[settings_name] + insecure_mfa_levels := {"NONE", "LEVEL1"} + insecure_mfa_levels[settings.mfa] + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.ibm_iam_account_settings.%s.mfa", [settings_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'mfa' attribute should be 'LEVEL2' or 'LEVEL3'", + "keyActualValue": sprintf("'mfa' attribute is set to '%s'", [settings.mfa]), + } } \ No newline at end of file From 5a59ec30e7ba192d9ee5641389f4515a338661c2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:51 +0100 Subject: [PATCH 753/900] chore: translate Spanish comments to English in negative1.tf --- .../ibm/ibm_iam_account_mfa_disabled/test/negative1.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/negative1.tf b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/negative1.tf index 0ca8fbb6935..f37bc112e9f 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/negative1.tf +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/negative1.tf @@ -1,4 +1,4 @@ -resource "ibm_iam_account_settings" "iam_secure" { - # CORRECTO: LEVEL2 es seguro - mfa = "LEVEL2" +resource "ibm_iam_account_settings" "iam_secure" { + # PASS: LEVEL2 es seguro + mfa = "LEVEL2" } \ No newline at end of file From 0bee53bf092ca797f9decfb9cbbc09e640dc39f1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:52 +0100 Subject: [PATCH 754/900] chore: translate Spanish comments to English in positive2.tf --- .../ibm/ibm_iam_account_mfa_disabled/test/positive2.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive2.tf b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive2.tf index 2435762e151..8b49fe44bae 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive2.tf +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive2.tf @@ -1,4 +1,4 @@ -resource "ibm_iam_account_settings" "iam_no_mfa" { - # Falta el atributo mfa - session_expiration_in_seconds = 3600 +resource "ibm_iam_account_settings" "iam_no_mfa" { + # Missing The attribute mfa + session_expiration_in_seconds = 3600 } \ No newline at end of file From 42a8b9548f31c816b0a9e9c3ed451a983476f8d9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:54 +0100 Subject: [PATCH 755/900] chore: translate Spanish comments to English in positive3.tf --- .../ibm/ibm_iam_account_mfa_disabled/test/positive3.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive3.tf b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive3.tf index 8c8a160cf24..7713e1ce6c1 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive3.tf +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/test/positive3.tf @@ -1,4 +1,4 @@ -resource "ibm_iam_account_settings" "iam_weak_mfa" { - # FALLO: LEVEL1 no es suficientemente seguro - mfa = "LEVEL1" +resource "ibm_iam_account_settings" "iam_weak_mfa" { + # FAIL: LEVEL1 no es suficientemente seguro + mfa = "LEVEL1" } \ No newline at end of file From ba66f9730964e9e9e0742f67adfc6ab778fd901a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:18:56 +0100 Subject: [PATCH 756/900] chore: translate Spanish comments to English in query.rego --- .../ibm/ibm_iam_session_expiration_too_long/query.rego | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/query.rego b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/query.rego index 3e6476c9d32..89f23ea7753 100644 --- a/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/query.rego +++ b/assets/queries/terraform/ibm/ibm_iam_session_expiration_too_long/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.common as common_lib -# REGLA 1: Falta el atributo 'session_expiration_in_seconds'. +# RULE 1: Missing The attribute 'session_expiration_in_seconds'. CxPolicy[result] { doc := input.document[i] settings := doc.resource.ibm_iam_account_settings[name] @@ -19,7 +19,7 @@ CxPolicy[result] { } } -# REGLA 2: La sesión dura más de 1 hora (3600 segundos). +# RULE 2: La sesión dura más de 1 hora (3600 segundos). CxPolicy[result] { doc := input.document[i] settings := doc.resource.ibm_iam_account_settings[name] From 1d23db1912c4877323fa60a8e043c05d32008d33 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:19:01 +0100 Subject: [PATCH 757/900] chore: translate Spanish comments to English in query.rego --- .../ibm/ibm_instance_os_disk_encryption_manual/query.rego | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/query.rego b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/query.rego index 0693449d1b0..8a4faa7db54 100644 --- a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/query.rego +++ b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/query.rego @@ -5,7 +5,7 @@ import data.generic.common as common_lib ensure_array(x) = x { is_array(x) } ensure_array(x) = [x] { not is_array(x) } -# CASO 1: Bloque 'boot_volume' totalmente ausente. +# CASE 1: Bloque 'boot_volume' totalmente missing. CxPolicy[result] { doc := input.document[i] instance := doc.resource.ibm_is_instance[name] @@ -22,7 +22,7 @@ CxPolicy[result] { } } -# CASO 2: Bloque 'boot_volume' presente, pero falta 'encryption'. +# CASE 2: Bloque 'boot_volume' presente, but Missing 'encryption'. CxPolicy[result] { doc := input.document[i] instance := doc.resource.ibm_is_instance[name] From 63528ef7007f14f40cf8da51ca6ba993420419e9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:19:04 +0100 Subject: [PATCH 758/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive2.tf b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive2.tf index fdce8605450..a685f31398d 100644 --- a/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive2.tf +++ b/assets/queries/terraform/ibm/ibm_instance_os_disk_encryption_manual/test/positive2.tf @@ -1,10 +1,10 @@ -resource "ibm_is_instance" "vsi_no_encryption" { - name = "vsi-unprotected-boot" - image = "r006-12345678" - profile = "bx2-2x8" - - boot_volume { - name = "boot-disk-standard" - # FALLO: Falta atributo encryption - } +resource "ibm_is_instance" "vsi_no_encryption" { + name = "vsi-unprotected-boot" + image = "r006-12345678" + profile = "bx2-2x8" + + boot_volume { + name = "boot-disk-standard" + # FAIL: Missing atributo encryption + } } \ No newline at end of file From 6bc7500b2fcd58f991fbe8de4d3d065fd30b8a65 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:19:06 +0100 Subject: [PATCH 759/900] chore: translate Spanish comments to English in query.rego --- .../terraform/ibm/ibm_kms_key_rotation_disabled/query.rego | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/query.rego b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/query.rego index 2fcede3668c..21030a30386 100644 --- a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.common as common_lib -# REGLA 1: El bloque 'rotation_policy' está completamente ausente. +# RULE 1: The 'rotation_policy' block is completely missing. CxPolicy[result] { key := input.document[i].resource.ibm_kms_key[key_name] @@ -18,7 +18,7 @@ CxPolicy[result] { } } -# REGLA 2: El bloque 'rotation_policy' existe, pero le falta 'rotation_interval_month'. +# RULE 2: The block 'rotation_policy' Exists, but le Missing 'rotation_interval_month'. CxPolicy[result] { key := input.document[i].resource.ibm_kms_key[key_name] @@ -35,7 +35,7 @@ CxPolicy[result] { } } -# REGLA 3: 'rotation_interval_month' está explícitamente configurado como 0. +# RULE 3: 'rotation_interval_month' está explícitamente configurado como 0. CxPolicy[result] { key := input.document[i].resource.ibm_kms_key[key_name] From 4bef1a1a60c6c1f9ad39cdef8af7ded3db6b37ce Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:19:08 +0100 Subject: [PATCH 760/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive2.tf b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive2.tf index 0f08f497188..e9c5d7000c5 100644 --- a/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive2.tf +++ b/assets/queries/terraform/ibm/ibm_kms_key_rotation_disabled/test/positive2.tf @@ -1,9 +1,9 @@ -resource "ibm_kms_key" "key_empty_policy" { - instance_id = "guid-123" - key_name = "key-fails-2" - standard_key = false - - rotation_policy { - # Falta rotation_interval_month - } +resource "ibm_kms_key" "key_empty_policy" { + instance_id = "guid-123" + key_name = "key-fails-2" + standard_key = false + + rotation_policy { + # Missing rotation_interval_month + } } \ No newline at end of file From cd35bff03997881ce3fb7b71f075697c1d6d7202 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:19:10 +0100 Subject: [PATCH 761/900] chore: translate Spanish comments to English in query.rego --- .../terraform/ibm/ibm_logdna_archiving_disabled/query.rego | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/query.rego b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/query.rego index dce95c0ba77..f96f09c586b 100644 --- a/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_logdna_archiving_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.common as common_lib -# REGLA: Detectar instancias de LogDNA que no tienen un recurso de archivado asociado. +# REGLA: Detectar instancias de LogDNA que no tienen un resource de archivado asociado. CxPolicy[result] { doc := input.document[i] _ := doc.resource.ibm_logdna_instance[instance_name] From ce98993b31f1906aa34e4748301e8f7c47175666 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:19:12 +0100 Subject: [PATCH 762/900] chore: translate Spanish comments to English in query.rego --- .../terraform/ibm/ibm_logdna_view_without_alert/query.rego | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/query.rego b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/query.rego index 06565b0b143..987301ed89f 100644 --- a/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/query.rego +++ b/assets/queries/terraform/ibm/ibm_logdna_view_without_alert/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.common as common_lib -# REGLA: Detectar vistas de LogDNA que no tienen ninguna alerta asociada. +# REGLA: Detectar vistas de LogDNA que no tienen NO alerta asociada. CxPolicy[result] { doc := input.document[i] view := doc.resource.ibm_logdna_view[view_name] From d000d5792de2e4b84d67231455c9eb6885f8cd48 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:21:31 +0100 Subject: [PATCH 763/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 102 +++++++++--------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego index a2087acc3d1..9e2b8325c48 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego @@ -1,53 +1,53 @@ -package Cx - -# REGLA 1: No existe ningún recurso 'oci_cloud_guard_configuration'. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - all_cloud_guards := [cg | - cg := input.document[_].resource.oci_cloud_guard_configuration[_] - ] - - count(all_cloud_guards) == 0 - - result := { - "documentId": doc.id, +package Cx + +# RULE 1: Does not exist ningún resource 'oci_cloud_guard_configuration'. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + all_cloud_guards := [cg | + cg := input.document[_].resource.oci_cloud_guard_configuration[_] + ] + + count(all_cloud_guards) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "Resource 'oci_cloud_guard_configuration' should exist to enable Cloud Guard", - "keyActualValue": "Resource 'oci_cloud_guard_configuration' is missing", - } -} - -# REGLA 2: Cloud Guard existe, pero su 'status' no es 'ENABLED'. -CxPolicy[result] { - cg := input.document[i].resource.oci_cloud_guard_configuration[cg_name] - - cg.status != "ENABLED" - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_cloud_guard_configuration.%s.status", [cg_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'status' attribute should be 'ENABLED'", - "keyActualValue": sprintf("'status' attribute is '%s'", [cg.status]), - } -} - -# REGLA 3: Cloud Guard existe y está habilitado, pero no en el compartimento raíz. -CxPolicy[result] { - cg := input.document[i].resource.oci_cloud_guard_configuration[cg_name] - - cg.status == "ENABLED" - not contains(lower(cg.compartment_id), "tenancy") - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_cloud_guard_configuration.%s.compartment_id", [cg_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'compartment_id' should be the tenancy (root compartment) OCID", - "keyActualValue": "'compartment_id' is not the tenancy OCID", - } + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "Resource 'oci_cloud_guard_configuration' should exist to enable Cloud Guard", + "keyActualValue": "Resource 'oci_cloud_guard_configuration' is missing", + } +} + +# RULE 2: Cloud Guard Exists, but su 'status' no es 'ENABLED'. +CxPolicy[result] { + cg := input.document[i].resource.oci_cloud_guard_configuration[cg_name] + + cg.status != "ENABLED" + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_cloud_guard_configuration.%s.status", [cg_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'status' attribute should be 'ENABLED'", + "keyActualValue": sprintf("'status' attribute is '%s'", [cg.status]), + } +} + +# RULE 3: Cloud Guard Exists y is enabled, but no en el compartimento raíz. +CxPolicy[result] { + cg := input.document[i].resource.oci_cloud_guard_configuration[cg_name] + + cg.status == "ENABLED" + not contains(lower(cg.compartment_id), "tenancy") + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_cloud_guard_configuration.%s.compartment_id", [cg_name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'compartment_id' should be the tenancy (root compartment) OCID", + "keyActualValue": "'compartment_id' is not the tenancy OCID", + } } \ No newline at end of file From 07e37c694334b5f4c49ba4afc9dfe8e51e1b5394 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:21:32 +0100 Subject: [PATCH 764/900] chore: translate Spanish comments to English in negative1.tf --- .../test/negative1.tf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/negative1.tf b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/negative1.tf index 062b0c647e3..32298f5a97c 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/negative1.tf +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/negative1.tf @@ -1,10 +1,10 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_cloud_guard_configuration" "cg_correct" { - # CORRECTO: Contiene la palabra "tenancy" - compartment_id = var.tenancy_ocid - reporting_region = "us-ashburn-1" - status = "ENABLED" +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_cloud_guard_configuration" "cg_correct" { + # PASS: Contiene la palabra "tenancy" + compartment_id = var.tenancy_ocid + reporting_region = "us-ashburn-1" + status = "ENABLED" } \ No newline at end of file From f46707e32650ad9151601c90f51b5da52e28c4ae Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:21:35 +0100 Subject: [PATCH 765/900] chore: translate Spanish comments to English in positive3.tf --- .../test/positive3.tf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive3.tf b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive3.tf index ee69e810d6b..d2a1791c282 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive3.tf +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/test/positive3.tf @@ -1,10 +1,10 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_cloud_guard_configuration" "cg_child" { - # FALLO: Apunta a un compartimento hijo, no al tenancy - compartment_id = var.child_compartment_id - reporting_region = "us-ashburn-1" - status = "ENABLED" +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_cloud_guard_configuration" "cg_child" { + # FAIL: Apunta a un compartimento hijo, no al tenancy + compartment_id = var.child_compartment_id + reporting_region = "us-ashburn-1" + status = "ENABLED" } \ No newline at end of file From 7189e7887c406c5abc4d96e59a85e1bf49806437 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:21:37 +0100 Subject: [PATCH 766/900] chore: translate Spanish comments to English in query.rego --- .../oci/oci_compute_legacy_metadata_enabled/query.rego | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/query.rego b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/query.rego index 0786620bb8a..01b0b89b3c8 100644 --- a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/query.rego +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.common as common_lib -# REGLA 1: Falta el bloque 'agent_config' por completo. +# RULE 1: Missing The block 'agent_config' por completo. CxPolicy[result] { instance := input.document[i].resource.oci_core_instance[instance_name] @@ -18,7 +18,7 @@ CxPolicy[result] { } } -# REGLA 2: Existe 'agent_config', pero falta el atributo dentro. +# RULE 2: Exists 'agent_config', but Missing The attribute dentro. CxPolicy[result] { instance := input.document[i].resource.oci_core_instance[instance_name] agent_config := instance.agent_config @@ -27,7 +27,7 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, - # AQUI ESTA EL CAMBIO: Apuntamos al bloque agent_config + # AQUI ESTA EL CAMBIO: Pointing to the block agent_config "searchKey": sprintf("resource.oci_core_instance.%s.agent_config", [instance_name]), "searchLine": common_lib.build_search_line(["resource", "oci_core_instance", instance_name, "agent_config"], []), "issueType": "MissingAttribute", @@ -36,7 +36,7 @@ CxPolicy[result] { } } -# REGLA 3: El atributo existe pero es 'false'. +# RULE 3: The attribute Exists but es 'false'. CxPolicy[result] { instance := input.document[i].resource.oci_core_instance[instance_name] From 77dabe7de231f5b454cd158945d436101a900d06 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:21:38 +0100 Subject: [PATCH 767/900] chore: translate Spanish comments to English in negative1.tf --- .../test/negative1.tf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/negative1.tf b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/negative1.tf index 548be50c429..46daa2c7707 100644 --- a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/negative1.tf +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/negative1.tf @@ -1,10 +1,10 @@ -resource "oci_core_instance" "negative1" { - availability_domain = "AD-1" - compartment_id = "ocid1.compartment..." - shape = "VM.Standard2.1" - - agent_config { - # CORRECTO - are_legacy_imds_endpoints_disabled = true - } +resource "oci_core_instance" "negative1" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + + agent_config { + # PASS + are_legacy_imds_endpoints_disabled = true + } } \ No newline at end of file From d06659e9afa53ade489d18de2474075048b594f9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:21:40 +0100 Subject: [PATCH 768/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive1.tf b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive1.tf index 0eb1571db93..980f71c8410 100644 --- a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive1.tf +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive1.tf @@ -1,6 +1,6 @@ -resource "oci_core_instance" "positive1" { - availability_domain = "AD-1" - compartment_id = "ocid1.compartment..." - shape = "VM.Standard2.1" - # FALLO: Falta agent_config (Caso 1) +resource "oci_core_instance" "positive1" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + # FAIL: Missing agent_config (Caso 1) } \ No newline at end of file From 8f46a5f18daeffcf2c6d8ef041ac4324bdc38086 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:21:41 +0100 Subject: [PATCH 769/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive2.tf b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive2.tf index 2cbe5ac1ad0..6193e1f812f 100644 --- a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive2.tf @@ -1,10 +1,10 @@ -resource "oci_core_instance" "positive2" { - availability_domain = "AD-1" - compartment_id = "ocid1.compartment..." - shape = "VM.Standard2.1" - - agent_config { - # FALLO: Falta atributo (Caso 2) - is_monitoring_disabled = false - } +resource "oci_core_instance" "positive2" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + + agent_config { + # FAIL: Missing atributo (Caso 2) + is_monitoring_disabled = false + } } \ No newline at end of file From 0e6d85a1ec5dc38f7df7e8d75754ca28e259fe6c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:21:43 +0100 Subject: [PATCH 770/900] chore: translate Spanish comments to English in positive3.tf --- .../test/positive3.tf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive3.tf b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive3.tf index e1e52522238..01ade141b02 100644 --- a/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive3.tf +++ b/assets/queries/terraform/oci/oci_compute_legacy_metadata_enabled/test/positive3.tf @@ -1,10 +1,10 @@ -resource "oci_core_instance" "positive3" { - availability_domain = "AD-1" - compartment_id = "ocid1.compartment..." - shape = "VM.Standard2.1" - - agent_config { - # FALLO: Valor incorrecto (Caso 3) - are_legacy_imds_endpoints_disabled = false - } +resource "oci_core_instance" "positive3" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard2.1" + + agent_config { + # FAIL: Valor incorrecto (Caso 3) + are_legacy_imds_endpoints_disabled = false + } } \ No newline at end of file From 2d36b062562c314cf047d52d537a31dd653e068a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:21:48 +0100 Subject: [PATCH 771/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 152 +++++++++--------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego index df0dd3b0aff..d58c6f05d9f 100644 --- a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego @@ -1,78 +1,78 @@ -package Cx - -expected_event_types := [ - "com.oraclecloud.identity.creategroup", - "com.oraclecloud.identity.updategroup", - "com.oraclecloud.identity.deletegroup" -] - -# REGLA 1: Missing (Global) -# No existe NINGUNA regla en el proyecto que monitoree eventos de IAM (ni siquiera parcialmente). -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - any_iam_rule := [rule | - rule := input.document[_].resource.oci_events_rule[_] - - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(any_iam_rule) == 0 - - result := { - "documentId": doc.id, +package Cx + +expected_event_types := [ + "com.oraclecloud.identity.creategroup", + "com.oraclecloud.identity.updategroup", + "com.oraclecloud.identity.deletegroup" +] + +# RULE 1: Missing (Global) +# No rule exists in the project monitoring events de IAM (ni siquiera parcialmente). +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_iam_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_iam_rule) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "An 'oci_events_rule' for IAM group changes should exist", - "keyActualValue": "No 'oci_events_rule' found for IAM group changes", - } -} - -# REGLA 2: Incomplete (Local) -# La regla existe y mira eventos de IAM, pero le falta alguno de los 3 requeridos. -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(matches) > 0 - count(matches) < count(expected_event_types) - - missing_count := count(expected_event_types) - count(matches) - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "The rule condition should include all 3 IAM group events (create, update, delete)", - "keyActualValue": sprintf("The rule is missing %d IAM group event(s)", [missing_count]), - } -} - -# REGLA 3: Disabled (Local) -# La regla tiene todos los eventos correctos, pero está deshabilitada. -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - count(matches) == count(expected_event_types) - - rule.is_enabled == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'is_enabled' should be true", - "keyActualValue": "'is_enabled' is false", - } + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for IAM group changes should exist", + "keyActualValue": "No 'oci_events_rule' found for IAM group changes", + } +} + +# RULE 2: Incomplete (Local) +# The rule Exists y mira events de IAM, but le Missing alguno de los 3 requeridos. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 3 IAM group events (create, update, delete)", + "keyActualValue": sprintf("The rule is missing %d IAM group event(s)", [missing_count]), + } +} + +# RULE 3: Disabled (Local) +# The rule has all the correct events but is disabled. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) == count(expected_event_types) + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } } \ No newline at end of file From 488f27d16b4b23868d73fe91b41f810ed67c1951 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:21:51 +0100 Subject: [PATCH 772/900] chore: translate Spanish comments to English in positive3.tf --- .../test/positive3.tf | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/positive3.tf b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/positive3.tf index 0fb787b6c2d..d1b4b7b2691 100644 --- a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/positive3.tf +++ b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/test/positive3.tf @@ -1,24 +1,24 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_events_rule" "disabled_rule" { - display_name = "DisabledRule" - # FALLO: Deshabilitada - is_enabled = false - - condition = < Date: Wed, 15 Apr 2026 22:21:53 +0100 Subject: [PATCH 773/900] chore: translate Spanish comments to English in query.rego --- .../oci/oci_iam_password_expiration_manual/query.rego | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/query.rego b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/query.rego index eff2729dac6..f9101349b5f 100644 --- a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/query.rego +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.common as common_lib -# CASO 1: Identity Domains - Expiración (password_expires_after) > 365. +# CASE 1: Identity Domains - Expiración (password_expires_after) > 365. CxPolicy[result] { doc := input.document[i] policy := doc.resource.oci_identity_domains_password_policy[name] @@ -19,7 +19,7 @@ CxPolicy[result] { } } -# CASO 2: Identity Domains - Atributo faltante. +# CASE 2: Identity Domains - Atributo faltante. CxPolicy[result] { doc := input.document[i] policy := doc.resource.oci_identity_domains_password_policy[name] @@ -36,7 +36,7 @@ CxPolicy[result] { } } -# CASO 3: IAM Clásico (Legacy) - Manual. +# CASE 3: IAM Clásico (Legacy) - Manual. CxPolicy[result] { doc := input.document[i] _ := doc.resource.oci_identity_authentication_policy[name] From f111cd31b223d64654bd69c704fb13036675f8c5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:21:55 +0100 Subject: [PATCH 774/900] chore: translate Spanish comments to English in negative1.tf --- .../test/negative1.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/negative1.tf b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/negative1.tf index bfbf8914113..cae1cb705e5 100644 --- a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/negative1.tf +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/negative1.tf @@ -1,7 +1,7 @@ -resource "oci_identity_domains_password_policy" "correct_policy" { - idcs_endpoint = "https://idcs-..." - name = "CorrectPolicy" - # CORRECTO: <= 365 - password_expires_after = 90 - schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] +resource "oci_identity_domains_password_policy" "correct_policy" { + idcs_endpoint = "https://idcs-..." + name = "CorrectPolicy" + # PASS: <= 365 + password_expires_after = 90 + schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] } \ No newline at end of file From 5523202ee1fc65f572b87d9bea63bdb6e63701fb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:21:56 +0100 Subject: [PATCH 775/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive1.tf b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive1.tf index 55fbf6400cb..8914da615c8 100644 --- a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive1.tf +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive1.tf @@ -1,7 +1,7 @@ -resource "oci_identity_domains_password_policy" "long_expiration" { - idcs_endpoint = "https://idcs-..." - name = "LongExpirationPolicy" - # FALLO: > 365 - password_expires_after = 400 - schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] +resource "oci_identity_domains_password_policy" "long_expiration" { + idcs_endpoint = "https://idcs-..." + name = "LongExpirationPolicy" + # FAIL: > 365 + password_expires_after = 400 + schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] } \ No newline at end of file From 0e10e088919a623f5dac72434244c1565814220d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:21:58 +0100 Subject: [PATCH 776/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive2.tf b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive2.tf index 2f876028117..767d4cf518a 100644 --- a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive2.tf @@ -1,7 +1,7 @@ -resource "oci_identity_domains_password_policy" "missing_attr" { - idcs_endpoint = "https://idcs-..." - name = "MissingAttrPolicy" - # FALLO: Falta el atributo - password_min_length = 14 - schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] +resource "oci_identity_domains_password_policy" "missing_attr" { + idcs_endpoint = "https://idcs-..." + name = "MissingAttrPolicy" + # FAIL: Missing The attribute + password_min_length = 14 + schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] } \ No newline at end of file From 45dc7c8f2525dd74110b89ee483e81efc7d89a42 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:00 +0100 Subject: [PATCH 777/900] chore: translate Spanish comments to English in positive3.tf --- .../test/positive3.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive3.tf b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive3.tf index 22742fb6d8c..12d29e73775 100644 --- a/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive3.tf +++ b/assets/queries/terraform/oci/oci_iam_password_expiration_manual/test/positive3.tf @@ -1,7 +1,7 @@ -resource "oci_identity_authentication_policy" "legacy_policy" { - compartment_id = "ocid1.tenancy..." - # FALLO: Legacy - password_policy { - minimum_password_length = 14 - } +resource "oci_identity_authentication_policy" "legacy_policy" { + compartment_id = "ocid1.tenancy..." + # FAIL: Legacy + password_policy { + minimum_password_length = 14 + } } \ No newline at end of file From 4acf10afab49d3e5e351752cfb001276e7190210 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:01 +0100 Subject: [PATCH 778/900] chore: translate Spanish comments to English in query.rego --- .../terraform/oci/oci_iam_password_policy_length/query.rego | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/query.rego b/assets/queries/terraform/oci/oci_iam_password_policy_length/query.rego index a1c6a3eae39..1cf143862d3 100644 --- a/assets/queries/terraform/oci/oci_iam_password_policy_length/query.rego +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/query.rego @@ -5,7 +5,7 @@ import data.generic.common as common_lib ensure_array(x) = x { is_array(x) } ensure_array(x) = [x] { is_object(x) } -# CASO 1: El bloque 'password_policy' EXISTE, pero el valor es menor a 14. +# CASE 1: The block 'password_policy' Exists, but el valor es menor a 14. CxPolicy[result] { doc := input.document[i] resource := doc.resource.oci_identity_authentication_policy[name] @@ -28,7 +28,7 @@ CxPolicy[result] { } } -# CASO 2: El bloque 'password_policy' EXISTE, pero FALTA el atributo 'minimum_password_length'. +# CASE 2: The block 'password_policy' Exists, but Missing The attribute 'minimum_password_length'. CxPolicy[result] { doc := input.document[i] resource := doc.resource.oci_identity_authentication_policy[name] @@ -49,7 +49,7 @@ CxPolicy[result] { } } -# CASO 3: El bloque 'password_policy' NO EXISTE en absoluto. +# CASE 3: The block 'password_policy' Does not exist en absoluto. CxPolicy[result] { doc := input.document[i] resource := doc.resource.oci_identity_authentication_policy[name] From e4e196185ce3011986a3865d78098baa98726c5f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:03 +0100 Subject: [PATCH 779/900] chore: translate Spanish comments to English in negative1.tf --- .../test/negative1.tf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/negative1.tf b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/negative1.tf index b302379143f..3ddc8e37095 100644 --- a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/negative1.tf +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/negative1.tf @@ -1,9 +1,9 @@ -resource "oci_identity_authentication_policy" "secure_policy" { - compartment_id = "ocid1.tenancy..." - - password_policy { - # CORRECTO: >= 14 - minimum_password_length = 14 - is_lowercase_characters_required = true - } +resource "oci_identity_authentication_policy" "secure_policy" { + compartment_id = "ocid1.tenancy..." + + password_policy { + # PASS: >= 14 + minimum_password_length = 14 + is_lowercase_characters_required = true + } } \ No newline at end of file From 0900bb97853ed144728f9fbc9e4b37f955bd310f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:04 +0100 Subject: [PATCH 780/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive1.tf b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive1.tf index 4b2edc6c686..70f9b9c8e23 100644 --- a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive1.tf +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive1.tf @@ -1,9 +1,9 @@ -resource "oci_identity_authentication_policy" "weak_policy" { - compartment_id = "ocid1.tenancy..." - - password_policy { - # FALLO: 8 es menor que 14 - minimum_password_length = 8 - is_lowercase_characters_required = true - } +resource "oci_identity_authentication_policy" "weak_policy" { + compartment_id = "ocid1.tenancy..." + + password_policy { + # FAIL: 8 es menor que 14 + minimum_password_length = 8 + is_lowercase_characters_required = true + } } \ No newline at end of file From 2f9c2cf0fa0fa249de3d072572ba4d1fec202a32 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:06 +0100 Subject: [PATCH 781/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive2.tf b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive2.tf index 02c3737ba9b..bc2df3dcadc 100644 --- a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive2.tf @@ -1,8 +1,8 @@ -resource "oci_identity_authentication_policy" "missing_attr" { - compartment_id = "ocid1.tenancy..." - - password_policy { - # FALLO: Falta minimum_password_length - is_lowercase_characters_required = true - } +resource "oci_identity_authentication_policy" "missing_attr" { + compartment_id = "ocid1.tenancy..." + + password_policy { + # FAIL: Missing minimum_password_length + is_lowercase_characters_required = true + } } \ No newline at end of file From d492cb07f9376609d22a20c4ca613024d24d0cbf Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:07 +0100 Subject: [PATCH 782/900] chore: translate Spanish comments to English in positive3.tf --- .../oci/oci_iam_password_policy_length/test/positive3.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive3.tf b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive3.tf index 6d4ed4fa8d6..78477dc8e41 100644 --- a/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive3.tf +++ b/assets/queries/terraform/oci/oci_iam_password_policy_length/test/positive3.tf @@ -1,4 +1,4 @@ -resource "oci_identity_authentication_policy" "missing_block" { - compartment_id = "ocid1.tenancy..." - # FALLO: No hay bloque password_policy +resource "oci_identity_authentication_policy" "missing_block" { + compartment_id = "ocid1.tenancy..." + # FAIL: No hay bloque password_policy } \ No newline at end of file From 7a04e526ca0a5a27f534a53547307a8ff709efed Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:09 +0100 Subject: [PATCH 783/900] chore: translate Spanish comments to English in query.rego --- .../terraform/oci/oci_iam_password_reuse_manual/query.rego | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/query.rego b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/query.rego index 61850f3e67e..7ffe03882f4 100644 --- a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/query.rego +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.common as common_lib -# CASO 1: Identity Domains - Historial insuficiente (< 24). +# CASE 1: Identity Domains - Historial insuficiente (< 24). CxPolicy[result] { doc := input.document[i] policy := doc.resource.oci_identity_domains_password_policy[name] @@ -19,7 +19,7 @@ CxPolicy[result] { } } -# CASO 2: Identity Domains - Atributo faltante. +# CASE 2: Identity Domains - Atributo faltante. CxPolicy[result] { doc := input.document[i] policy := doc.resource.oci_identity_domains_password_policy[name] @@ -36,7 +36,7 @@ CxPolicy[result] { } } -# CASO 3: IAM Clásico (Legacy) - Manual. +# CASE 3: IAM Clásico (Legacy) - Manual. CxPolicy[result] { doc := input.document[i] _ := doc.resource.oci_identity_authentication_policy[name] From 378c51e8614fd0ea239ce69d033fbaf779a43b6d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:11 +0100 Subject: [PATCH 784/900] chore: translate Spanish comments to English in negative1.tf --- .../test/negative1.tf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/negative1.tf b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/negative1.tf index e551ec5346e..afa1fa17928 100644 --- a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/negative1.tf +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/negative1.tf @@ -1,9 +1,9 @@ -resource "oci_identity_domains_password_policy" "secure_policy" { - idcs_endpoint = "https://idcs-..." - name = "SecurePolicy" - - # CORRECTO: >= 24 - num_passwords_in_history = 24 - - schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] +resource "oci_identity_domains_password_policy" "secure_policy" { + idcs_endpoint = "https://idcs-..." + name = "SecurePolicy" + + # PASS: >= 24 + num_passwords_in_history = 24 + + schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] } \ No newline at end of file From 77fba54acfe42b473f6ed6144180feefb66904b5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:12 +0100 Subject: [PATCH 785/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive1.tf b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive1.tf index 8087a0e07ff..45269292598 100644 --- a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive1.tf +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive1.tf @@ -1,9 +1,9 @@ -resource "oci_identity_domains_password_policy" "weak_history" { - idcs_endpoint = "https://idcs-..." - name = "WeakHistoryPolicy" - - # FALLO: 5 es menor que 24 - num_passwords_in_history = 5 - - schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] +resource "oci_identity_domains_password_policy" "weak_history" { + idcs_endpoint = "https://idcs-..." + name = "WeakHistoryPolicy" + + # FAIL: 5 es menor que 24 + num_passwords_in_history = 5 + + schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] } \ No newline at end of file From f052594212ccef1bacf8a7f895f988e61b93b827 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:14 +0100 Subject: [PATCH 786/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive2.tf b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive2.tf index c57df4600ae..a105c5cc4f2 100644 --- a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive2.tf @@ -1,8 +1,8 @@ -resource "oci_identity_domains_password_policy" "missing_attr" { - idcs_endpoint = "https://idcs-..." - name = "MissingAttrPolicy" - - # FALLO: Falta num_passwords_in_history - password_min_length = 14 - schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] +resource "oci_identity_domains_password_policy" "missing_attr" { + idcs_endpoint = "https://idcs-..." + name = "MissingAttrPolicy" + + # FAIL: Missing num_passwords_in_history + password_min_length = 14 + schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:extension:passwordState:User"] } \ No newline at end of file From cb8775df1efbb7dea3ca5bbe489f855647b1fc07 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:15 +0100 Subject: [PATCH 787/900] chore: translate Spanish comments to English in positive3.tf --- .../test/positive3.tf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive3.tf b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive3.tf index 63251d16ce5..1a164a880c4 100644 --- a/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive3.tf +++ b/assets/queries/terraform/oci/oci_iam_password_reuse_manual/test/positive3.tf @@ -1,8 +1,8 @@ -resource "oci_identity_authentication_policy" "legacy_policy" { - compartment_id = "ocid1.tenancy..." - - # FALLO: Recurso Legacy requiere chequeo manual - password_policy { - minimum_password_length = 14 - } +resource "oci_identity_authentication_policy" "legacy_policy" { + compartment_id = "ocid1.tenancy..." + + # FAIL: resource Legacy requiere chequeo manual + password_policy { + minimum_password_length = 14 + } } \ No newline at end of file From 34da58819f303cf092933d244c0fe65f9cc7b482 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:17 +0100 Subject: [PATCH 788/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 150 +++++++++--------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego index c1f51e6e269..bb0523dfec3 100644 --- a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego @@ -1,77 +1,77 @@ -package Cx - -expected_event_types := [ - "com.oraclecloud.identity.createpolicy", - "com.oraclecloud.identity.updatepolicy", - "com.oraclecloud.identity.deletepolicy" -] - -# REGLA 1: Missing (Global) -# No existe NINGUNA regla en el proyecto que monitoree eventos de Políticas IAM. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - any_policy_rule := [rule | - rule := input.document[_].resource.oci_events_rule[_] - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(any_policy_rule) == 0 - - result := { - "documentId": doc.id, +package Cx + +expected_event_types := [ + "com.oraclecloud.identity.createpolicy", + "com.oraclecloud.identity.updatepolicy", + "com.oraclecloud.identity.deletepolicy" +] + +# RULE 1: Missing (Global) +# No rule exists in the project monitoring events de Políticas IAM. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_policy_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_policy_rule) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "An 'oci_events_rule' for IAM Policy changes should exist", - "keyActualValue": "No 'oci_events_rule' found for IAM Policy changes", - } -} - -# REGLA 2: Incomplete (Local) -# La regla existe y mira eventos de Políticas, pero le falta alguno de los 3 requeridos. -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(matches) > 0 - count(matches) < count(expected_event_types) - - missing_count := count(expected_event_types) - count(matches) - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "The rule condition should include all 3 IAM Policy events (create, update, delete)", - "keyActualValue": sprintf("The rule is missing %d IAM Policy event(s)", [missing_count]), - } -} - -# REGLA 3: Disabled (Local) -# La regla tiene todos los eventos correctos, pero está deshabilitada. -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - count(matches) == count(expected_event_types) - - rule.is_enabled == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'is_enabled' should be true", - "keyActualValue": "'is_enabled' is false", - } + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for IAM Policy changes should exist", + "keyActualValue": "No 'oci_events_rule' found for IAM Policy changes", + } +} + +# RULE 2: Incomplete (Local) +# The rule Exists y mira events de Políticas, but le Missing alguno de los 3 requeridos. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 3 IAM Policy events (create, update, delete)", + "keyActualValue": sprintf("The rule is missing %d IAM Policy event(s)", [missing_count]), + } +} + +# RULE 3: Disabled (Local) +# The rule has all the correct events but is disabled. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) == count(expected_event_types) + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } } \ No newline at end of file From 64d0f0cfc3cc727dfda0f7d0a8dc40f10595511c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:19 +0100 Subject: [PATCH 789/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive2.tf index 48dcc79c9b4..7f95191417f 100644 --- a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive2.tf @@ -1,25 +1,25 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_events_rule" "incomplete_rule" { - display_name = "IncompletePolicyRule" - compartment_id = "ocid1.tenancy.oc1.." - is_enabled = true - - # FALLO: Falta "deletepolicy" - condition = jsonencode({ - "eventType": [ - "com.oraclecloud.identity.createpolicy", - "com.oraclecloud.identity.updatepolicy" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = "ocid1.onstopic.oc1.." - is_enabled = true - } - } +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "incomplete_rule" { + display_name = "IncompletePolicyRule" + compartment_id = "ocid1.tenancy.oc1.." + is_enabled = true + + # FAIL: Missing "deletepolicy" + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identity.createpolicy", + "com.oraclecloud.identity.updatepolicy" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic.oc1.." + is_enabled = true + } + } } \ No newline at end of file From 696ab62987865cfbed140b9d2bae525faa318c07 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:23 +0100 Subject: [PATCH 790/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 154 +++++++++--------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego index 8d109df061c..2207ee786e3 100644 --- a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego @@ -1,79 +1,79 @@ -package Cx - -expected_event_types := [ - "com.oraclecloud.identity.createuser", - "com.oraclecloud.identity.updateuser", - "com.oraclecloud.identity.deleteuser", - "com.oraclecloud.identity.enableuser", - "com.oraclecloud.identity.disableuser" -] - -# REGLA 1: Missing (Global) -# No existe NINGUNA regla en el proyecto que monitoree eventos de usuarios. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - any_user_rule := [rule | - rule := input.document[_].resource.oci_events_rule[_] - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(any_user_rule) == 0 - - result := { - "documentId": doc.id, +package Cx + +expected_event_types := [ + "com.oraclecloud.identity.createuser", + "com.oraclecloud.identity.updateuser", + "com.oraclecloud.identity.deleteuser", + "com.oraclecloud.identity.enableuser", + "com.oraclecloud.identity.disableuser" +] + +# RULE 1: Missing (Global) +# No rule exists in the project monitoring events de usuarios. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_user_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_user_rule) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "An 'oci_events_rule' for IAM User changes (create, update, delete, enable, disable) should exist", - "keyActualValue": "No 'oci_events_rule' found for IAM User changes", - } -} - -# REGLA 2: Incomplete (Local) -# La regla existe y es relevante, pero le falta alguno de los 5 eventos. -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(matches) > 0 - count(matches) < count(expected_event_types) - - missing_count := count(expected_event_types) - count(matches) - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "The rule condition should include all 5 IAM User events", - "keyActualValue": sprintf("The rule is missing %d IAM User event(s)", [missing_count]), - } -} - -# REGLA 3: Disabled (Local) -# Si es una regla de Usuarios (relevante) y está apagada -> FALLO CRÍTICO. -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - count(matches) > 0 - - rule.is_enabled == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'is_enabled' should be true", - "keyActualValue": "'is_enabled' is false", - } + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for IAM User changes (create, update, delete, enable, disable) should exist", + "keyActualValue": "No 'oci_events_rule' found for IAM User changes", + } +} + +# RULE 2: Incomplete (Local) +# The rule Exists y es relevante, but le Missing alguno de los 5 events. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 5 IAM User events", + "keyActualValue": sprintf("The rule is missing %d IAM User event(s)", [missing_count]), + } +} + +# RULE 3: Disabled (Local) +# Si es una regla de Usuarios (relevante) y está apagada -> FALLO CRÍTICO. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) > 0 + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } } \ No newline at end of file From c700e5b5b313848a46064a36825d03030a7fe350 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:26 +0100 Subject: [PATCH 791/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive2.tf index 41ad4ef1343..68f93d89297 100644 --- a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/test/positive2.tf @@ -1,25 +1,25 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_events_rule" "incomplete_user_rule" { - display_name = "IncompleteUserRule" - compartment_id = "ocid1.tenancy..." - is_enabled = true - - # FALLO: Faltan enableuser y disableuser - condition = jsonencode({ - "eventType": [ - "com.oraclecloud.identity.createuser", - "com.oraclecloud.identity.updateuser", - "com.oraclecloud.identity.deleteuser" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = "ocid1.onstopic..." - } - } +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "incomplete_user_rule" { + display_name = "IncompleteUserRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + # FAIL: Faltan enableuser y disableuser + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.identity.createuser", + "com.oraclecloud.identity.updateuser", + "com.oraclecloud.identity.deleteuser" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } } \ No newline at end of file From cce33c8440c586159b53a58dc399239db0a6d3ac Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:28 +0100 Subject: [PATCH 792/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego index 82fd26b90f9..27bbef7790a 100644 --- a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego @@ -1,44 +1,44 @@ -package Cx - -expected_event := "com.oraclecloud.identitycontrolplane.updateidentityprovider" - -# REGLA 1: Missing (Global) -# No existe NINGUNA regla en el proyecto que monitoree el evento de Identity Provider. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - any_idp_rule := [rule | - rule := input.document[_].resource.oci_events_rule[_] - contains(rule.condition, expected_event) - ] - - count(any_idp_rule) == 0 - - result := { - "documentId": doc.id, +package Cx + +expected_event := "com.oraclecloud.identitycontrolplane.updateidentityprovider" + +# RULE 1: Missing (Global) +# No rule exists in the project monitoring el evento de Identity Provider. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_idp_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + contains(rule.condition, expected_event) + ] + + count(any_idp_rule) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "An 'oci_events_rule' for Identity Provider changes should exist", - "keyActualValue": "No 'oci_events_rule' found for Identity Provider changes", - } -} - -# REGLA 2: Disabled (Local) -# La regla existe y monitorea IdP, pero está deshabilitada. -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - contains(rule.condition, expected_event) - - rule.is_enabled == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'is_enabled' should be true", - "keyActualValue": "'is_enabled' is false", - } + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for Identity Provider changes should exist", + "keyActualValue": "No 'oci_events_rule' found for Identity Provider changes", + } +} + +# RULE 2: Disabled (Local) +# The rule Exists y monitorea IdP, but is disabled. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + contains(rule.condition, expected_event) + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } } \ No newline at end of file From 683d23181d01fc4a453f2a09c158ef0c4049da26 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:31 +0100 Subject: [PATCH 793/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego index d844640863e..c8dc1f9b5a0 100644 --- a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego @@ -1,44 +1,44 @@ -package Cx - -expected_event := "com.oraclecloud.identitycontrolplane.updateidpgroupmapping" - -# REGLA 1: Missing (Global) -# No existe NINGUNA regla en el proyecto que monitoree el evento de IdP Group Mapping. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - any_mapping_rule := [rule | - rule := input.document[_].resource.oci_events_rule[_] - contains(rule.condition, expected_event) - ] - - count(any_mapping_rule) == 0 - - result := { - "documentId": doc.id, +package Cx + +expected_event := "com.oraclecloud.identitycontrolplane.updateidpgroupmapping" + +# RULE 1: Missing (Global) +# No rule exists in the project monitoring el evento de IdP Group Mapping. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_mapping_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + contains(rule.condition, expected_event) + ] + + count(any_mapping_rule) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "An 'oci_events_rule' for IdP group mapping changes should exist", - "keyActualValue": "No 'oci_events_rule' found for IdP group mapping changes", - } -} - -# REGLA 2: Disabled (Local) -# La regla existe y monitorea el mapeo, pero está deshabilitada. -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - contains(rule.condition, expected_event) - - rule.is_enabled == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'is_enabled' should be true", - "keyActualValue": "'is_enabled' is false", - } + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for IdP group mapping changes should exist", + "keyActualValue": "No 'oci_events_rule' found for IdP group mapping changes", + } +} + +# RULE 2: Disabled (Local) +# The rule Exists y monitorea el mapeo, but is disabled. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + contains(rule.condition, expected_event) + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } } \ No newline at end of file From 4bf2e757c807541415b819ec75ee4ff3b2cced98 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:34 +0100 Subject: [PATCH 794/900] chore: translate Spanish comments to English in query.rego --- .../oci/oci_instance_transit_encryption/query.rego | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/query.rego b/assets/queries/terraform/oci/oci_instance_transit_encryption/query.rego index 5bd4e5f6031..60bf3ed6718 100644 --- a/assets/queries/terraform/oci/oci_instance_transit_encryption/query.rego +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/query.rego @@ -5,7 +5,7 @@ import data.generic.common as common_lib ensure_array(x) = x { is_array(x) } ensure_array(x) = [x] { is_object(x) } -# CASO 1: El bloque launch_options existe, pero la opción está explícitamente en FALSE. +# CASE 1: The block launch_options Exists, but la opción está explícitamente en FALSE. CxPolicy[result] { doc := input.document[i] instance := doc.resource.oci_core_instance[name] @@ -25,7 +25,7 @@ CxPolicy[result] { } } -# CASO 2: El bloque launch_options existe, pero FALTA el atributo (default es false/inseguro). +# CASE 2: The block launch_options Exists, but Missing The attribute (default es false/inseguro). CxPolicy[result] { doc := input.document[i] instance := doc.resource.oci_core_instance[name] @@ -45,7 +45,7 @@ CxPolicy[result] { } } -# CASO 3: FALTA el bloque launch_options completo. +# CASE 3: Missing The block launch_options completo. CxPolicy[result] { doc := input.document[i] instance := doc.resource.oci_core_instance[name] From 3eda2be1588f7432d2aedede8e4c650124080a08 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:36 +0100 Subject: [PATCH 795/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive1.tf b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive1.tf index a0fc32fdc32..990adbac80a 100644 --- a/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive1.tf +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive1.tf @@ -1,20 +1,20 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_core_instance" "instance_explicit_false" { - availability_domain = "AD-1" - compartment_id = "ocid1.compartment..." - shape = "VM.Standard.E4.Flex" - - launch_options { - boot_volume_type = "PARAVIRTUALIZED" - # FALLO: Explícitamente false (sin comentario pegado encima) - is_pv_encryption_in_transit_enabled = false - } - - source_details { - source_id = "ocid1.image..." - source_type = "image" - } +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_instance" "instance_explicit_false" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard.E4.Flex" + + launch_options { + boot_volume_type = "PARAVIRTUALIZED" + # FAIL: Explícitamente false (sin comentario pegado encima) + is_pv_encryption_in_transit_enabled = false + } + + source_details { + source_id = "ocid1.image..." + source_type = "image" + } } \ No newline at end of file From 5b59388621c1f673e6855ef3c082d76bf27b6bda Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:37 +0100 Subject: [PATCH 796/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive2.tf b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive2.tf index 3a1ca5f3519..eecaed77dab 100644 --- a/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive2.tf @@ -1,15 +1,15 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_core_instance" "instance_missing_attribute" { - availability_domain = "AD-1" - compartment_id = "ocid1.compartment..." - shape = "VM.Standard.E4.Flex" - - # El bloque existe, pero falta el atributo de encriptación - launch_options { - boot_volume_type = "PARAVIRTUALIZED" - network_type = "PARAVIRTUALIZED" - } +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_instance" "instance_missing_attribute" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard.E4.Flex" + + # The block Exists, but Missing The attribute de encriptación + launch_options { + boot_volume_type = "PARAVIRTUALIZED" + network_type = "PARAVIRTUALIZED" + } } \ No newline at end of file From 02483dfdab589d58ae1dd01abf1babc70fb61b5e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:39 +0100 Subject: [PATCH 797/900] chore: translate Spanish comments to English in positive3.tf --- .../test/positive3.tf | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive3.tf b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive3.tf index a6da327c592..fdbb89e89c0 100644 --- a/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive3.tf +++ b/assets/queries/terraform/oci/oci_instance_transit_encryption/test/positive3.tf @@ -1,15 +1,15 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_core_instance" "instance_missing_block" { - availability_domain = "AD-1" - compartment_id = "ocid1.compartment..." - shape = "VM.Standard.E4.Flex" - - # No existe el bloque launch_options - source_details { - source_id = "ocid1.image..." - source_type = "image" - } +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_core_instance" "instance_missing_block" { + availability_domain = "AD-1" + compartment_id = "ocid1.compartment..." + shape = "VM.Standard.E4.Flex" + + # Does not exist The block launch_options + source_details { + source_id = "ocid1.image..." + source_type = "image" + } } \ No newline at end of file From 368a978a9f5e6720162030c59d44cd71a70d260c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:40 +0100 Subject: [PATCH 798/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego index 8a9f9b32ba3..b08119f3ad8 100644 --- a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego @@ -1,44 +1,44 @@ -package Cx - -expected_event := "com.oraclecloud.identity.localuser.authenticate" - -# REGLA 1: Missing (Global) -# No existe NINGUNA regla en el proyecto que monitoree el evento de autenticación local. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - any_auth_rule := [rule | - rule := input.document[_].resource.oci_events_rule[_] - contains(rule.condition, expected_event) - ] - - count(any_auth_rule) == 0 - - result := { - "documentId": doc.id, +package Cx + +expected_event := "com.oraclecloud.identity.localuser.authenticate" + +# RULE 1: Missing (Global) +# No rule exists in the project monitoring el evento de autenticación local. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_auth_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + contains(rule.condition, expected_event) + ] + + count(any_auth_rule) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "An 'oci_events_rule' for local user authentication events should exist", - "keyActualValue": "No 'oci_events_rule' found for local user authentication", - } -} - -# REGLA 2: Disabled (Local) -# La regla existe y monitorea autenticación, pero está deshabilitada. -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - contains(rule.condition, expected_event) - - rule.is_enabled == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'is_enabled' should be true", - "keyActualValue": "'is_enabled' is false", - } + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for local user authentication events should exist", + "keyActualValue": "No 'oci_events_rule' found for local user authentication", + } +} + +# RULE 2: Disabled (Local) +# The rule Exists y monitorea autenticación, but is disabled. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + contains(rule.condition, expected_event) + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } } \ No newline at end of file From 25ab6e20ac48a9c1134309c12fd368359e51fce9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:43 +0100 Subject: [PATCH 799/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 174 +++++++++--------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego index 0a8f1dc9abf..c5bbf7b32b5 100644 --- a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego @@ -1,89 +1,89 @@ -package Cx - -expected_event_types := [ - "com.oraclecloud.virtualnetwork.createinternetgateway", - "com.oraclecloud.virtualnetwork.updateinternetgateway", - "com.oraclecloud.virtualnetwork.deleteinternetgateway", - "com.oraclecloud.virtualnetwork.createnatgateway", - "com.oraclecloud.virtualnetwork.updatenatgateway", - "com.oraclecloud.virtualnetwork.deletenatgateway", - "com.oraclecloud.virtualnetwork.createservicegateway", - "com.oraclecloud.virtualnetwork.updateservicegateway", - "com.oraclecloud.virtualnetwork.deleteservicegateway", - "com.oraclecloud.virtualnetwork.createdrg", - "com.oraclecloud.virtualnetwork.updatedrg", - "com.oraclecloud.virtualnetwork.deletedrg", - "com.oraclecloud.virtualnetwork.createlocalpeeringgateway", - "com.oraclecloud.virtualnetwork.updatelocalpeeringgateway", - "com.oraclecloud.virtualnetwork.deletelocalpeeringgateway" -] - -# REGLA 1: Missing (Global) -# No existe NINGUNA regla en el proyecto que monitoree Gateways. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - any_gateway_rule := [rule | - rule := input.document[_].resource.oci_events_rule[_] - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(any_gateway_rule) == 0 - - result := { - "documentId": doc.id, +package Cx + +expected_event_types := [ + "com.oraclecloud.virtualnetwork.createinternetgateway", + "com.oraclecloud.virtualnetwork.updateinternetgateway", + "com.oraclecloud.virtualnetwork.deleteinternetgateway", + "com.oraclecloud.virtualnetwork.createnatgateway", + "com.oraclecloud.virtualnetwork.updatenatgateway", + "com.oraclecloud.virtualnetwork.deletenatgateway", + "com.oraclecloud.virtualnetwork.createservicegateway", + "com.oraclecloud.virtualnetwork.updateservicegateway", + "com.oraclecloud.virtualnetwork.deleteservicegateway", + "com.oraclecloud.virtualnetwork.createdrg", + "com.oraclecloud.virtualnetwork.updatedrg", + "com.oraclecloud.virtualnetwork.deletedrg", + "com.oraclecloud.virtualnetwork.createlocalpeeringgateway", + "com.oraclecloud.virtualnetwork.updatelocalpeeringgateway", + "com.oraclecloud.virtualnetwork.deletelocalpeeringgateway" +] + +# RULE 1: Missing (Global) +# No rule exists in the project monitoring Gateways. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_gateway_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_gateway_rule) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "An 'oci_events_rule' for Network Gateway changes should exist", - "keyActualValue": "No 'oci_events_rule' found for Network Gateway changes", - } -} - -# REGLA 2: Incomplete (Local) -# La regla existe, pero le faltan eventos (ej. tiene IGW pero falta NAT). -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(matches) > 0 - count(matches) < count(expected_event_types) - - missing_count := count(expected_event_types) - count(matches) - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "The rule condition should include all 15 Network Gateway events", - "keyActualValue": sprintf("The rule is missing %d Network Gateway event(s)", [missing_count]), - } -} - -# REGLA 3: Disabled (Local) -# La regla es relevante (gateways) pero está apagada. -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - count(matches) > 0 - - rule.is_enabled == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'is_enabled' should be true", - "keyActualValue": "'is_enabled' is false", - } + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for Network Gateway changes should exist", + "keyActualValue": "No 'oci_events_rule' found for Network Gateway changes", + } +} + +# RULE 2: Incomplete (Local) +# The rule Exists, but is missing events (ej. tiene IGW but Missing NAT). +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 15 Network Gateway events", + "keyActualValue": sprintf("The rule is missing %d Network Gateway event(s)", [missing_count]), + } +} + +# RULE 3: Disabled (Local) +# The rule es relevante (gateways) but está apagada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) > 0 + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } } \ No newline at end of file From 33977d014a2b60f4ed6d0eb94db4c5248f5a8d22 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:46 +0100 Subject: [PATCH 800/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive2.tf index 00a9fbefb4e..c479a1b6735 100644 --- a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/test/positive2.tf @@ -1,25 +1,25 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_events_rule" "incomplete_gateway_rule" { - display_name = "IncompleteGatewayRule" - compartment_id = "ocid1.tenancy..." - is_enabled = true - - # FALLO: Solo tiene Internet Gateway, faltan los otros 12 eventos - condition = jsonencode({ - "eventType": [ - "com.oraclecloud.virtualnetwork.createinternetgateway", - "com.oraclecloud.virtualnetwork.updateinternetgateway", - "com.oraclecloud.virtualnetwork.deleteinternetgateway" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = "ocid1.onstopic..." - } - } +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "incomplete_gateway_rule" { + display_name = "IncompleteGatewayRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + # FAIL: Solo tiene Internet Gateway, faltan los otros 12 events + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createinternetgateway", + "com.oraclecloud.virtualnetwork.updateinternetgateway", + "com.oraclecloud.virtualnetwork.deleteinternetgateway" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } } \ No newline at end of file From 5949ff5dbb401e5c1f70a2d9706cc83beaf5c561 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:48 +0100 Subject: [PATCH 801/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego index 3bd5c49babd..d6bc9c3e827 100644 --- a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego @@ -1,45 +1,45 @@ -package Cx - -# REGLA 1: Missing (Global) -# No existe ningún recurso 'oci_ons_notification_topic' en todo el documento. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - all_topics := [topic | - topic := input.document[_].resource.oci_ons_notification_topic[_] - ] - - count(all_topics) == 0 - - result := { - "documentId": doc.id, +package Cx + +# RULE 1: Missing (Global) +# Does not exist ningún resource 'oci_ons_notification_topic' en todo el documento. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + all_topics := [topic | + topic := input.document[_].resource.oci_ons_notification_topic[_] + ] + + count(all_topics) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "At least one 'oci_ons_notification_topic' resource should exist", - "keyActualValue": "No 'oci_ons_notification_topic' resource was found", - } -} - -# REGLA 2: Orphan Topic (Local) -# Existe un tópico, pero ninguna suscripción apunta a él. -CxPolicy[result] { - doc := input.document[i] - _ := doc.resource.oci_ons_notification_topic[topic_name] - - matching_subscriptions := [sub | - sub := input.document[_].resource.oci_ons_subscription[_] - contains(sub.topic_id, topic_name) - ] - - count(matching_subscriptions) == 0 - - result := { - "documentId": doc.id, - "searchKey": sprintf("resource.oci_ons_notification_topic.%s", [topic_name]), - "issueType": "MissingAttribute", - "keyExpectedValue": "'oci_ons_notification_topic' should have at least one associated 'oci_ons_subscription'", - "keyActualValue": "'oci_ons_notification_topic' has no subscriptions", - } + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "At least one 'oci_ons_notification_topic' resource should exist", + "keyActualValue": "No 'oci_ons_notification_topic' resource was found", + } +} + +# RULE 2: Orphan Topic (Local) +# Exists un tópico, but NO suscripción apunta a él. +CxPolicy[result] { + doc := input.document[i] + _ := doc.resource.oci_ons_notification_topic[topic_name] + + matching_subscriptions := [sub | + sub := input.document[_].resource.oci_ons_subscription[_] + contains(sub.topic_id, topic_name) + ] + + count(matching_subscriptions) == 0 + + result := { + "documentId": doc.id, + "searchKey": sprintf("resource.oci_ons_notification_topic.%s", [topic_name]), + "issueType": "MissingAttribute", + "keyExpectedValue": "'oci_ons_notification_topic' should have at least one associated 'oci_ons_subscription'", + "keyActualValue": "'oci_ons_notification_topic' has no subscriptions", + } } \ No newline at end of file From 37d12f16383c2157bdc13d49bd8edc329b42ef65 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:50 +0100 Subject: [PATCH 802/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive2.tf b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive2.tf index 45e44aa7f54..4264e303256 100644 --- a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/test/positive2.tf @@ -1,9 +1,9 @@ -provider "oci" { - region = "us-ashburn-1" -} - -# Caso: Tópico existe pero no tiene suscripción que lo apunte -resource "oci_ons_notification_topic" "orphan_topic" { - compartment_id = "ocid1.compartment..." - name = "orphan-topic" +provider "oci" { + region = "us-ashburn-1" +} + +# Caso: Tópico Exists but no tiene suscripción que lo apunte +resource "oci_ons_notification_topic" "orphan_topic" { + compartment_id = "ocid1.compartment..." + name = "orphan-topic" } \ No newline at end of file From dd440b47f9aaef9f20ff5aa000a423fe30224b25 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:52 +0100 Subject: [PATCH 803/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 150 +++++++++--------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego index b0f6ea3d8c9..37c84f0b62e 100644 --- a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego @@ -1,77 +1,77 @@ -package Cx - -expected_event_types := [ - "com.oraclecloud.virtualnetwork.createnetworksecuritygroup", - "com.oraclecloud.virtualnetwork.updatenetworksecuritygroup", - "com.oraclecloud.virtualnetwork.deletenetworksecuritygroup" -] - -# REGLA 1: Missing (Global) -# No existe NINGUNA regla en el proyecto que monitoree NSGs. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - any_nsg_rule := [rule | - rule := input.document[_].resource.oci_events_rule[_] - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(any_nsg_rule) == 0 - - result := { - "documentId": doc.id, +package Cx + +expected_event_types := [ + "com.oraclecloud.virtualnetwork.createnetworksecuritygroup", + "com.oraclecloud.virtualnetwork.updatenetworksecuritygroup", + "com.oraclecloud.virtualnetwork.deletenetworksecuritygroup" +] + +# RULE 1: Missing (Global) +# No rule exists in the project monitoring NSGs. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_nsg_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_nsg_rule) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "An 'oci_events_rule' for Network Security Group changes should exist", - "keyActualValue": "No 'oci_events_rule' found for Network Security Group changes", - } -} - -# REGLA 2: Incomplete (Local) -# La regla existe, pero le faltan eventos (ej: tiene create pero falta delete). -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(matches) > 0 - count(matches) < count(expected_event_types) - - missing_count := count(expected_event_types) - count(matches) - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "The rule condition should include all 3 NSG events (create, update, delete)", - "keyActualValue": sprintf("The rule is missing %d NSG event(s)", [missing_count]), - } -} - -# REGLA 3: Disabled (Local) -# La regla es relevante (NSG) pero está apagada. -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - count(matches) > 0 - - rule.is_enabled == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'is_enabled' should be true", - "keyActualValue": "'is_enabled' is false", - } + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for Network Security Group changes should exist", + "keyActualValue": "No 'oci_events_rule' found for Network Security Group changes", + } +} + +# RULE 2: Incomplete (Local) +# The rule Exists, but is missing events (ej: tiene create but Missing delete). +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 3 NSG events (create, update, delete)", + "keyActualValue": sprintf("The rule is missing %d NSG event(s)", [missing_count]), + } +} + +# RULE 3: Disabled (Local) +# The rule es relevante (NSG) but está apagada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) > 0 + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } } \ No newline at end of file From 56b8c977e9ec5bb88353bb5d9daf9f74409098a5 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:54 +0100 Subject: [PATCH 804/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive2.tf index ecf21db2ea8..c9d898513ee 100644 --- a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/test/positive2.tf @@ -1,24 +1,24 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_events_rule" "incomplete_nsg_rule" { - display_name = "IncompleteNSGRule" - compartment_id = "ocid1.tenancy..." - is_enabled = true - - # FALLO: Falta "deletenetworksecuritygroup" - condition = jsonencode({ - "eventType": [ - "com.oraclecloud.virtualnetwork.createnetworksecuritygroup", - "com.oraclecloud.virtualnetwork.updatenetworksecuritygroup" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = "ocid1.onstopic..." - } - } +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "incomplete_nsg_rule" { + display_name = "IncompleteNSGRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + # FAIL: Missing "deletenetworksecuritygroup" + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createnetworksecuritygroup", + "com.oraclecloud.virtualnetwork.updatenetworksecuritygroup" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } } \ No newline at end of file From 6f9f4d48b259b049249f07cc05a5080a588de009 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:57 +0100 Subject: [PATCH 805/900] chore: translate Spanish comments to English in query.rego --- .../oci/oci_objectstorage_bucket_logging_enabled/query.rego | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/query.rego b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/query.rego index 0b570b9924f..a5b0caa273e 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/query.rego +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/query.rego @@ -2,8 +2,8 @@ package Cx import data.generic.common as common_lib -# REGLA 1: El atributo 'object_events_enabled' está ausente (MissingAttribute). -# Por defecto en OCI Terraform es false, así que su ausencia es un riesgo. +# RULE 1: The 'object_events_enabled' attribute is missing (MissingAttribute). +# Default in OCI Terraform is false, así que su ausencia es un riesgo. CxPolicy[result] { bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] @@ -19,7 +19,7 @@ CxPolicy[result] { } } -# REGLA 2: El atributo 'object_events_enabled' está explícitamente en 'false' (IncorrectValue). +# RULE 2: The attribute 'object_events_enabled' está explícitamente en 'false' (IncorrectValue). CxPolicy[result] { bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] From ac7f5c93ef41a3d252e3f8804486478d02ded61e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:22:58 +0100 Subject: [PATCH 806/900] chore: translate Spanish comments to English in negative1.tf --- .../test/negative1.tf | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/negative1.tf b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/negative1.tf index dcb5c904ef2..ae49e43d76b 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/negative1.tf +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/negative1.tf @@ -1,12 +1,12 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_objectstorage_bucket" "bucket_enabled_log" { - compartment_id = "ocid1.compartment.oc1..aaaa" - namespace = "my-namespace" - name = "bucket-secure" - - # CORRECTO - object_events_enabled = true +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_objectstorage_bucket" "bucket_enabled_log" { + compartment_id = "ocid1.compartment.oc1..aaaa" + namespace = "my-namespace" + name = "bucket-secure" + + # PASS + object_events_enabled = true } \ No newline at end of file From 5d01f05011c6e0828ed744034cafe6a8800d00ee Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:00 +0100 Subject: [PATCH 807/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive1.tf b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive1.tf index 3e1a2bfe185..74c9cd7b2cf 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive1.tf +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive1.tf @@ -1,11 +1,11 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_objectstorage_bucket" "bucket_missing_log" { - compartment_id = "ocid1.compartment.oc1..aaaa" - namespace = "my-namespace" - name = "bucket-no-logs" - access_type = "NoPublicAccess" - # FALLO: Falta object_events_enabled +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_objectstorage_bucket" "bucket_missing_log" { + compartment_id = "ocid1.compartment.oc1..aaaa" + namespace = "my-namespace" + name = "bucket-no-logs" + access_type = "NoPublicAccess" + # FAIL: Missing object_events_enabled } \ No newline at end of file From beef9531835eb0c1fb8125bce948807803918759 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:01 +0100 Subject: [PATCH 808/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive2.tf b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive2.tf index bac22f14e63..b9b5711d050 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_logging_enabled/test/positive2.tf @@ -1,12 +1,12 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_objectstorage_bucket" "bucket_disabled_log" { - compartment_id = "ocid1.compartment.oc1..aaaa" - namespace = "my-namespace" - name = "bucket-disabled-logs" - - # FALLO: Explícitamente false - object_events_enabled = false +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_objectstorage_bucket" "bucket_disabled_log" { + compartment_id = "ocid1.compartment.oc1..aaaa" + namespace = "my-namespace" + name = "bucket-disabled-logs" + + # FAIL: Explícitamente false + object_events_enabled = false } \ No newline at end of file From 07cad64d8a0bc845007184b05f3a17a938a01447 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:03 +0100 Subject: [PATCH 809/900] chore: translate Spanish comments to English in query.rego --- .../oci_objectstorage_bucket_versioning_disabled/query.rego | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/query.rego b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/query.rego index d28c37f7c62..5715e6650ca 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/query.rego +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/query.rego @@ -2,8 +2,8 @@ package Cx import data.generic.common as common_lib -# REGLA 1: El atributo 'versioning' está ausente en el bucket. -# Por defecto, si no se especifica, el versionado está deshabilitado. +# RULE 1: The 'versioning' attribute is missing en el bucket. +# Por defecto, si no se especifica, el versionado is disabled. CxPolicy[result] { bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] @@ -19,7 +19,7 @@ CxPolicy[result] { } } -# REGLA 2: El atributo 'versioning' existe pero no es 'Enabled'. +# RULE 2: The attribute 'versioning' Exists but no es 'Enabled'. # Puede ser 'Disabled' o 'Suspended'. CxPolicy[result] { bucket := input.document[i].resource.oci_objectstorage_bucket[bucket_name] From 91607071e8e593f1ff7c31e9dd2666ca169c4a93 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:05 +0100 Subject: [PATCH 810/900] chore: translate Spanish comments to English in negative1.tf --- .../test/negative1.tf | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/negative1.tf b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/negative1.tf index 466b92b441c..bd9f34d3613 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/negative1.tf +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/negative1.tf @@ -1,12 +1,12 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_objectstorage_bucket" "bucket_enabled_versioning" { - compartment_id = "ocid1.compartment.oc1..aaaa" - namespace = "my-namespace" - name = "bucket-secure" - - # CORRECTO - versioning = "Enabled" +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_objectstorage_bucket" "bucket_enabled_versioning" { + compartment_id = "ocid1.compartment.oc1..aaaa" + namespace = "my-namespace" + name = "bucket-secure" + + # PASS + versioning = "Enabled" } \ No newline at end of file From 7ec0935c6280e96e7de17cb478d365bd71da2eb2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:06 +0100 Subject: [PATCH 811/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive1.tf b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive1.tf index a23885af982..563d15ca649 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive1.tf +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive1.tf @@ -1,11 +1,11 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_objectstorage_bucket" "bucket_missing_versioning" { - compartment_id = "ocid1.compartment.oc1..aaaa" - namespace = "my-namespace" - name = "bucket-no-ver" - access_type = "NoPublicAccess" - # FALLO: Falta el atributo versioning +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_objectstorage_bucket" "bucket_missing_versioning" { + compartment_id = "ocid1.compartment.oc1..aaaa" + namespace = "my-namespace" + name = "bucket-no-ver" + access_type = "NoPublicAccess" + # FAIL: Missing The attribute versioning } \ No newline at end of file From 4f8389ff562461dbf8de53ba59a270ea93577f43 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:08 +0100 Subject: [PATCH 812/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive2.tf b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive2.tf index 7730d44e087..2dfc0b7fd1b 100644 --- a/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_objectstorage_bucket_versioning_disabled/test/positive2.tf @@ -1,12 +1,12 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_objectstorage_bucket" "bucket_suspended_versioning" { - compartment_id = "ocid1.compartment.oc1..aaaa" - namespace = "my-namespace" - name = "bucket-suspended" - - # FALLO: Está suspendido - versioning = "Suspended" +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_objectstorage_bucket" "bucket_suspended_versioning" { + compartment_id = "ocid1.compartment.oc1..aaaa" + namespace = "my-namespace" + name = "bucket-suspended" + + # FAIL: Está suspendido + versioning = "Suspended" } \ No newline at end of file From 56296f07606971d2450eb7510c68e69a3314eab6 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:12 +0100 Subject: [PATCH 813/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 150 +++++++++--------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego index f299c2b7fe6..7315c3e9b83 100644 --- a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego @@ -1,77 +1,77 @@ -package Cx - -expected_event_types := [ - "com.oraclecloud.virtualnetwork.createroutetable", - "com.oraclecloud.virtualnetwork.updateroutetable", - "com.oraclecloud.virtualnetwork.deleteroutetable" -] - -# REGLA 1: Missing (Global) -# No existe NINGUNA regla en el proyecto que monitoree Route Tables. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - any_rt_rule := [rule | - rule := input.document[_].resource.oci_events_rule[_] - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(any_rt_rule) == 0 - - result := { - "documentId": doc.id, +package Cx + +expected_event_types := [ + "com.oraclecloud.virtualnetwork.createroutetable", + "com.oraclecloud.virtualnetwork.updateroutetable", + "com.oraclecloud.virtualnetwork.deleteroutetable" +] + +# RULE 1: Missing (Global) +# No rule exists in the project monitoring Route Tables. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_rt_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_rt_rule) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "An 'oci_events_rule' for Route Table changes should exist", - "keyActualValue": "No 'oci_events_rule' found for Route Table changes", - } -} - -# REGLA 2: Incomplete (Local) -# La regla existe, pero le faltan eventos (ej: tiene create pero falta update). -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(matches) > 0 - count(matches) < count(expected_event_types) - - missing_count := count(expected_event_types) - count(matches) - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "The rule condition should include all 3 Route Table events (create, update, delete)", - "keyActualValue": sprintf("The rule is missing %d Route Table event(s)", [missing_count]), - } -} - -# REGLA 3: Disabled (Local) -# La regla es relevante (Route Table) pero está apagada. -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - count(matches) > 0 - - rule.is_enabled == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'is_enabled' should be true", - "keyActualValue": "'is_enabled' is false", - } + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for Route Table changes should exist", + "keyActualValue": "No 'oci_events_rule' found for Route Table changes", + } +} + +# RULE 2: Incomplete (Local) +# The rule Exists, but is missing events (ej: tiene create but Missing update). +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 3 Route Table events (create, update, delete)", + "keyActualValue": sprintf("The rule is missing %d Route Table event(s)", [missing_count]), + } +} + +# RULE 3: Disabled (Local) +# The rule es relevante (Route Table) but está apagada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) > 0 + + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } } \ No newline at end of file From 8a35c7f70948062376d3cabfa991e2492e2f4b71 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:14 +0100 Subject: [PATCH 814/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive2.tf b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive2.tf index 74025ee37c7..33a56a3fca4 100644 --- a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/test/positive2.tf @@ -1,24 +1,24 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_events_rule" "incomplete_rt_rule" { - display_name = "IncompleteRTRule" - compartment_id = "ocid1.tenancy..." - is_enabled = true - - # FALLO: Falta "deleteroutetable" - condition = jsonencode({ - "eventType": [ - "com.oraclecloud.virtualnetwork.createroutetable", - "com.oraclecloud.virtualnetwork.updateroutetable" - ] - }) - - actions { - actions { - action_type = "ONS" - topic_id = "ocid1.onstopic..." - } - } +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_events_rule" "incomplete_rt_rule" { + display_name = "IncompleteRTRule" + compartment_id = "ocid1.tenancy..." + is_enabled = true + + # FAIL: Missing "deleteroutetable" + condition = jsonencode({ + "eventType": [ + "com.oraclecloud.virtualnetwork.createroutetable", + "com.oraclecloud.virtualnetwork.updateroutetable" + ] + }) + + actions { + actions { + action_type = "ONS" + topic_id = "ocid1.onstopic..." + } + } } \ No newline at end of file From 443824074339eabf0f36ad15ba069cce217407e2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:16 +0100 Subject: [PATCH 815/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 148 +++++++++--------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego index a37133baf4c..eb7027efa2c 100644 --- a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego @@ -1,76 +1,76 @@ -package Cx - -expected_event_types := [ - "com.oraclecloud.virtualnetwork.createsecuritylist", - "com.oraclecloud.virtualnetwork.updatesecuritylist", - "com.oraclecloud.virtualnetwork.deletesecuritylist" -] - -# REGLA 1: Missing (Global) -# No existe ninguna regla en el proyecto que monitoree Security Lists. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - any_sl_rule := [rule | - rule := input.document[_].resource.oci_events_rule[_] - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(any_sl_rule) == 0 - - result := { - "documentId": doc.id, +package Cx + +expected_event_types := [ + "com.oraclecloud.virtualnetwork.createsecuritylist", + "com.oraclecloud.virtualnetwork.updatesecuritylist", + "com.oraclecloud.virtualnetwork.deletesecuritylist" +] + +# RULE 1: Missing (Global) +# No rule exists in the project monitoring Security Lists. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_sl_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_sl_rule) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "An 'oci_events_rule' for Security List changes should exist", - "keyActualValue": "No 'oci_events_rule' found for Security List changes", - } -} - -# REGLA 2: Incomplete (Local) -# La regla existe pero le faltan eventos (ej: tiene create pero falta delete). -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(matches) > 0 - count(matches) < count(expected_event_types) - - missing_count := count(expected_event_types) - count(matches) - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "The rule condition should include all 3 Security List events (create, update, delete)", - "keyActualValue": sprintf("The rule is missing %d Security List event(s)", [missing_count]), - } -} - -# REGLA 3: Disabled (Local) -# La regla es relevante para Security Lists pero está apagada. -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - count(matches) > 0 - rule.is_enabled == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'is_enabled' should be true", - "keyActualValue": "'is_enabled' is false", - } + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for Security List changes should exist", + "keyActualValue": "No 'oci_events_rule' found for Security List changes", + } +} + +# RULE 2: Incomplete (Local) +# The rule exists but is missing events (ej: tiene create but Missing delete). +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 3 Security List events (create, update, delete)", + "keyActualValue": sprintf("The rule is missing %d Security List event(s)", [missing_count]), + } +} + +# RULE 3: Disabled (Local) +# The rule es relevante para Security Lists but está apagada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) > 0 + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } } \ No newline at end of file From 7a46a0a70739ffc66b4d75a81d36031836cdd5ac Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:20 +0100 Subject: [PATCH 816/900] chore: translate Spanish comments to English in negative1.tf --- .../test/negative1.tf | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative1.tf b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative1.tf index 907698d9916..e8f247c6e45 100644 --- a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative1.tf +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative1.tf @@ -1,13 +1,13 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_identity_policy" "read_only_storage" { - name = "ReadOnlyStorage" - compartment_id = "ocid1.tenancy..." - - # CORRECTO: El verbo es read, no incluye delete - statements = [ - "Allow group Auditors to read object-family in tenancy" - ] +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_policy" "read_only_storage" { + name = "ReadOnlyStorage" + compartment_id = "ocid1.tenancy..." + + # PASS: El verbo es read, no incluye delete + statements = [ + "Allow group Auditors to read object-family in tenancy" + ] } \ No newline at end of file From 78646b0f01d1c615b0f21c91cc63b9dc916fff61 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:22 +0100 Subject: [PATCH 817/900] chore: translate Spanish comments to English in negative2.tf --- .../test/negative2.tf | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative2.tf b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative2.tf index 74f3d0745ba..873d9452098 100644 --- a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative2.tf +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/negative2.tf @@ -1,13 +1,13 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_identity_policy" "false_positive_check" { - name = "ManagerCheck" - compartment_id = "ocid1.tenancy..." - - # CORRECTO: Aunque el grupo se llama Managers, el verbo es read. El regex \bmanage\b evita el fallo. - statements = [ - "Allow group ObjectManagers to read object-family in tenancy" - ] +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_policy" "false_positive_check" { + name = "ManagerCheck" + compartment_id = "ocid1.tenancy..." + + # PASS: Aunque el grupo se llama Managers, el verbo es read. El regex \bmanage\b evita el fallo. + statements = [ + "Allow group ObjectManagers to read object-family in tenancy" + ] } \ No newline at end of file From 291471d418e8f642acf62cd8872106e864200e66 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:23 +0100 Subject: [PATCH 818/900] chore: translate Spanish comments to English in positive1.tf --- .../test/positive1.tf | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive1.tf b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive1.tf index 4ea3bcac30a..ad77ded208f 100644 --- a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive1.tf +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive1.tf @@ -1,13 +1,13 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_identity_policy" "unsafe_object_admin" { - name = "UnsafeObjectAdmin" - compartment_id = "ocid1.tenancy..." - - # FALLO: Otorga manage (incluye delete) en object-family - statements = [ - "Allow group StorageAdmins to manage object-family in tenancy" - ] +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_policy" "unsafe_object_admin" { + name = "UnsafeObjectAdmin" + compartment_id = "ocid1.tenancy..." + + # FAIL: Otorga manage (incluye delete) en object-family + statements = [ + "Allow group StorageAdmins to manage object-family in tenancy" + ] } \ No newline at end of file From 4276ca0960a4765bcc91d75792159fcd52d38429 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:25 +0100 Subject: [PATCH 819/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive2.tf b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive2.tf index 4f5f8234695..7ae5cb0334d 100644 --- a/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_storage_admin_no_delete_manual/test/positive2.tf @@ -1,13 +1,13 @@ -provider "oci" { - region = "us-ashburn-1" -} - -resource "oci_identity_policy" "unsafe_volume_admin" { - name = "UnsafeVolumeAdmin" - compartment_id = "ocid1.tenancy..." - - # FALLO: Otorga manage (incluye delete) en volume-family - statements = [ - "Allow group BackupAdmins to MANAGE volume-family in tenancy" - ] +provider "oci" { + region = "us-ashburn-1" +} + +resource "oci_identity_policy" "unsafe_volume_admin" { + name = "UnsafeVolumeAdmin" + compartment_id = "ocid1.tenancy..." + + # FAIL: Otorga manage (incluye delete) en volume-family + statements = [ + "Allow group BackupAdmins to MANAGE volume-family in tenancy" + ] } \ No newline at end of file From a245280c519b28169f7e0a49ad0ae41a3a2c36fa Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:27 +0100 Subject: [PATCH 820/900] chore: translate Spanish comments to English in query.rego --- .../oci/oci_subnet_flow_logging_disabled/query.rego | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/query.rego b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/query.rego index 05e4b099a33..b558d9de386 100644 --- a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/query.rego +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/query.rego @@ -2,7 +2,7 @@ package Cx import data.generic.common as common_lib -# REGLA 1: No existe ningún log asociado a la subred (Missing) +# RULE 1: Does not exist ningún log asociado a la subred (Missing) CxPolicy[result] { doc := input.document[i] _ := doc.resource.oci_core_subnet[subnet_name] @@ -23,7 +23,7 @@ CxPolicy[result] { } } -# REGLA 2: Un log de flujo está deshabilitado +# RULE 2: Un log de flujo is disabled CxPolicy[result] { doc := input.document[i] log := doc.resource.oci_logging_log[log_name] @@ -42,7 +42,7 @@ CxPolicy[result] { } } -# REGLA 3: Un log de flujo tiene el tipo incorrecto +# RULE 3: Un log de flujo tiene el tipo incorrecto CxPolicy[result] { doc := input.document[i] log := doc.resource.oci_logging_log[log_name] @@ -60,7 +60,7 @@ CxPolicy[result] { } } -# REGLA 4: Un log de flujo tiene el servicio incorrecto +# RULE 4: Un log de flujo tiene el servicio incorrecto CxPolicy[result] { doc := input.document[i] log := doc.resource.oci_logging_log[log_name] From b9bb1cda6084dc256823577f1d0f671eb84159d0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:29 +0100 Subject: [PATCH 821/900] chore: translate Spanish comments to English in positive2.tf --- .../test/positive2.tf | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive2.tf b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive2.tf index 25b5435ae62..e8a48a44290 100644 --- a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive2.tf +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive2.tf @@ -1,15 +1,15 @@ -resource "oci_logging_log" "disabled_flow_log" { - display_name = "disabled_log" - log_group_id = "ocid1.loggroup.oc1..cccc" - log_type = "SERVICE" - - # FALLO: Deshabilitado - is_enabled = false - - configuration { - source { - resource = "ocid1.subnet.oc1..aaaa" - service = "flowlogs" - } - } +resource "oci_logging_log" "disabled_flow_log" { + display_name = "disabled_log" + log_group_id = "ocid1.loggroup.oc1..cccc" + log_type = "SERVICE" + + # FAIL: Deshabilitado + is_enabled = false + + configuration { + source { + resource = "ocid1.subnet.oc1..aaaa" + service = "flowlogs" + } + } } \ No newline at end of file From ab942210f4f7345a338c51b970876404d83b6e08 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:31 +0100 Subject: [PATCH 822/900] chore: translate Spanish comments to English in positive3.tf --- .../test/positive3.tf | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive3.tf b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive3.tf index 790e68430cb..d436f63e1d8 100644 --- a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive3.tf +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive3.tf @@ -1,15 +1,15 @@ -resource "oci_logging_log" "wrong_type_log" { - display_name = "wrong_type" - log_group_id = "ocid1.loggroup.oc1..cccc" - - # FALLO: Debería ser SERVICE - log_type = "CUSTOM" - is_enabled = true - - configuration { - source { - resource = "ocid1.subnet.oc1..aaaa" - service = "flowlogs" - } - } +resource "oci_logging_log" "wrong_type_log" { + display_name = "wrong_type" + log_group_id = "ocid1.loggroup.oc1..cccc" + + # FAIL: Debería ser SERVICE + log_type = "CUSTOM" + is_enabled = true + + configuration { + source { + resource = "ocid1.subnet.oc1..aaaa" + service = "flowlogs" + } + } } \ No newline at end of file From c6a2ec7ad93a1cc4fdc75a489281a3673483ec9a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:32 +0100 Subject: [PATCH 823/900] chore: translate Spanish comments to English in positive4.tf --- .../test/positive4.tf | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive4.tf b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive4.tf index b20dee2c0fa..326b7392d5e 100644 --- a/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive4.tf +++ b/assets/queries/terraform/oci/oci_subnet_flow_logging_disabled/test/positive4.tf @@ -1,14 +1,14 @@ -resource "oci_logging_log" "wrong_service_log" { - display_name = "wrong_service" - log_group_id = "ocid1.loggroup.oc1..cccc" - log_type = "SERVICE" - is_enabled = true - - configuration { - source { - resource = "ocid1.subnet.oc1..aaaa" - # FALLO: Debería ser flowlogs - service = "wronglogs" - } - } +resource "oci_logging_log" "wrong_service_log" { + display_name = "wrong_service" + log_group_id = "ocid1.loggroup.oc1..cccc" + log_type = "SERVICE" + is_enabled = true + + configuration { + source { + resource = "ocid1.subnet.oc1..aaaa" + # FAIL: Debería ser flowlogs + service = "wronglogs" + } + } } \ No newline at end of file From 7a71e58c349b9f655dbc85eb960acc282130c2ac Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:23:34 +0100 Subject: [PATCH 824/900] chore: translate Spanish comments to English in query.rego --- .../query.rego | 148 +++++++++--------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego index 7e44136b8bb..3520c4638fb 100644 --- a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego @@ -1,76 +1,76 @@ -package Cx - -expected_event_types := [ - "com.oraclecloud.virtualnetwork.createvcn", - "com.oraclecloud.virtualnetwork.updatevcn", - "com.oraclecloud.virtualnetwork.deletevcn" -] - -# REGLA 1: Missing (Global) -# No existe ninguna regla en el proyecto que monitoree cambios en VCNs. -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - any_vcn_rule := [rule | - rule := input.document[_].resource.oci_events_rule[_] - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(any_vcn_rule) == 0 - - result := { - "documentId": doc.id, +package Cx + +expected_event_types := [ + "com.oraclecloud.virtualnetwork.createvcn", + "com.oraclecloud.virtualnetwork.updatevcn", + "com.oraclecloud.virtualnetwork.deletevcn" +] + +# RULE 1: Missing (Global) +# No rule exists in the project monitoring cambios en VCNs. +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + any_vcn_rule := [rule | + rule := input.document[_].resource.oci_events_rule[_] + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(any_vcn_rule) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "An 'oci_events_rule' for VCN changes should exist", - "keyActualValue": "No 'oci_events_rule' found for VCN changes", - } -} - -# REGLA 2: Incomplete (Local) -# La regla existe pero le faltan eventos (ej: tiene create pero falta delete). -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - - count(matches) > 0 - count(matches) < count(expected_event_types) - - missing_count := count(expected_event_types) - count(matches) - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "The rule condition should include all 3 VCN events (create, update, delete)", - "keyActualValue": sprintf("The rule is missing %d VCN event(s)", [missing_count]), - } -} - -# REGLA 3: Disabled (Local) -# La regla es relevante para VCN pero está apagada. -CxPolicy[result] { - rule := input.document[i].resource.oci_events_rule[name] - - matches := [event | - event := expected_event_types[_] - contains(rule.condition, event) - ] - count(matches) > 0 - rule.is_enabled == false - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'is_enabled' should be true", - "keyActualValue": "'is_enabled' is false", - } + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for VCN changes should exist", + "keyActualValue": "No 'oci_events_rule' found for VCN changes", + } +} + +# RULE 2: Incomplete (Local) +# The rule exists but is missing events (ej: tiene create but Missing delete). +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + + count(matches) > 0 + count(matches) < count(expected_event_types) + + missing_count := count(expected_event_types) - count(matches) + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "The rule condition should include all 3 VCN events (create, update, delete)", + "keyActualValue": sprintf("The rule is missing %d VCN event(s)", [missing_count]), + } +} + +# RULE 3: Disabled (Local) +# The rule es relevante para VCN but está apagada. +CxPolicy[result] { + rule := input.document[i].resource.oci_events_rule[name] + + matches := [event | + event := expected_event_types[_] + contains(rule.condition, event) + ] + count(matches) > 0 + rule.is_enabled == false + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "issueType": "IncorrectValue", + "keyExpectedValue": "'is_enabled' should be true", + "keyActualValue": "'is_enabled' is false", + } } \ No newline at end of file From e6c14f3a2766bcec00fdf6ecd26e524c6e4ce882 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:31:24 +0100 Subject: [PATCH 825/900] refactor: use application_insights_keys list with count check in query --- .../query.rego | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego index e916ff5d40b..7fb4c00492d 100644 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/query.rego @@ -10,10 +10,15 @@ targets := { "azurerm_windows_function_app" } -# RULE 1: The 'app_settings' block does not exist at all. +application_insights_keys := [ + "APPLICATIONINSIGHTS_CONNECTION_STRING", + "APPINSIGHTS_INSTRUMENTATIONKEY", +] + +# RULE 1: The 'app_settings' block is missing entirely. CxPolicy[result] { doc := input.document[i] - resource_type := targets[t] + resource_type := targets[_] app := doc.resource[resource_type][name] not app.app_settings @@ -25,20 +30,20 @@ CxPolicy[result] { "searchKey": sprintf("%s[%s]", [resource_type, name]), "searchLine": common_lib.build_search_line(["resource", resource_type, name], []), "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'%s.%s' should have 'app_settings' defined", [resource_type, name]), + "keyExpectedValue": sprintf("'%s.%s' should have 'app_settings' with an Application Insights key configured", [resource_type, name]), "keyActualValue": sprintf("'%s.%s' is missing 'app_settings'", [resource_type, name]), } } -# RULE 2: The 'app_settings' block exists but does not have any App Insights key. +# RULE 2: 'app_settings' exists but neither Application Insights key is configured. +# Iterates application_insights_keys and counts how many are present; fires when none are found. CxPolicy[result] { doc := input.document[i] - resource_type := targets[t] + resource_type := targets[_] app := doc.resource[resource_type][name] app.app_settings - not app.app_settings["APPLICATIONINSIGHTS_CONNECTION_STRING"] - not app.app_settings["APPINSIGHTS_INSTRUMENTATIONKEY"] + count({k | k := application_insights_keys[_]; app.app_settings[k]}) == 0 result := { "documentId": doc.id, @@ -47,7 +52,7 @@ CxPolicy[result] { "searchKey": sprintf("%s[%s].app_settings", [resource_type, name]), "searchLine": common_lib.build_search_line(["resource", resource_type, name, "app_settings"], []), "issueType": "IncorrectValue", - "keyExpectedValue": "'app_settings' should contain 'APPLICATIONINSIGHTS_CONNECTION_STRING'", - "keyActualValue": "'app_settings' does not contain Application Insights configuration", + "keyExpectedValue": sprintf("'app_settings' should contain '%s' or '%s'", [application_insights_keys[0], application_insights_keys[1]]), + "keyActualValue": "'app_settings' does not contain any Application Insights configuration key", } } From 9ea53308e0bbd0e1d05aca9f9e4790a87f272624 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:31:25 +0100 Subject: [PATCH 826/900] docs: update descriptionUrl to Microsoft configure-monitoring docs --- .../metadata.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json index d19bd476079..7c3a4bc5640 100644 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/metadata.json @@ -4,11 +4,11 @@ "severity": "MEDIUM", "category": "Observability", "descriptionText": "Ensures that Azure App Services and Function Apps are linked to Application Insights for performance monitoring and error tracking.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_web_app#app_settings", + "descriptionUrl": "https://learn.microsoft.com/en-us/azure/azure-functions/configure-monitoring?tabs=v2#enable-application-insights-integration", "platform": "Terraform", "descriptionID": "721c26ff", "cloudProvider": "azure", "cwe": "778", "riskScore": "3.0", "experimental": "true" -} \ No newline at end of file +} From bb3fea5ed23b1839621c5c44cf3fb6215887b40d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:31:25 +0100 Subject: [PATCH 827/900] chore: translate Spanish comment to English in negative1.tf --- .../test/negative1.tf | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative1.tf b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative1.tf index a37f36b739b..e528d3c0ebc 100644 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative1.tf +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative1.tf @@ -1,11 +1,11 @@ -# Caso con Connection String (Recomendado) -resource "azurerm_linux_web_app" "pass_connection_string" { - name = "pass-app-1" - resource_group_name = "rg" - location = "West Europe" - service_plan_id = "plan-id" - - app_settings = { - "APPLICATIONINSIGHTS_CONNECTION_STRING" = "InstrumentationKey=0000;IngestionEndpoint=https://..." - } -} \ No newline at end of file +# Case: Connection String (Recommended) +resource "azurerm_linux_web_app" "pass_connection_string" { + name = "pass-app-1" + resource_group_name = "rg" + location = "West Europe" + service_plan_id = "plan-id" + + app_settings = { + "APPLICATIONINSIGHTS_CONNECTION_STRING" = "InstrumentationKey=0000;IngestionEndpoint=https://..." + } +} From db0caa6711df0450f255a32f4d7a6bf6acdf099f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:31:26 +0100 Subject: [PATCH 828/900] chore: translate Spanish comment to English in negative2.tf --- .../test/negative2.tf | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative2.tf b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative2.tf index 143f597f488..c719508e879 100644 --- a/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative2.tf +++ b/assets/queries/terraform/azure/azure_app_service_application_insights_not_configured/test/negative2.tf @@ -1,11 +1,11 @@ -# Caso con Instrumentation Key (Legacy) -resource "azurerm_windows_web_app" "pass_instrumentation_key" { - name = "pass-app-2" - resource_group_name = "rg" - location = "West Europe" - service_plan_id = "plan-id" - - app_settings = { - "APPINSIGHTS_INSTRUMENTATIONKEY" = "0000-0000-0000-0000" - } -} \ No newline at end of file +# Case: Instrumentation Key (Legacy) +resource "azurerm_windows_web_app" "pass_instrumentation_key" { + name = "pass-app-2" + resource_group_name = "rg" + location = "West Europe" + service_plan_id = "plan-id" + + app_settings = { + "APPINSIGHTS_INSTRUMENTATIONKEY" = "0000-0000-0000-0000" + } +} From 6b583939708231f072a9e6278e0634af49b752c1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:34:11 +0100 Subject: [PATCH 829/900] chore: remove azure_app_service_http_logs_disabled (duplicate of PR #7991) --- .../query.rego | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego deleted file mode 100644 index b448036ca87..00000000000 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/query.rego +++ /dev/null @@ -1,47 +0,0 @@ -package Cx - -import data.generic.common as common_lib -import data.generic.terraform as tf_lib - -targets := {"azurerm_linux_web_app", "azurerm_windows_web_app"} - -# RULE 1: The 'logs' block does not exist in the App Service. -CxPolicy[result] { - doc := input.document[i] - resource_type := targets[t] - app := doc.resource[resource_type][name] - - not app.logs - - result := { - "documentId": doc.id, - "resourceType": resource_type, - "resourceName": tf_lib.get_resource_name(app, name), - "searchKey": sprintf("%s[%s]", [resource_type, name]), - "searchLine": common_lib.build_search_line(["resource", resource_type, name], []), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'%s.%s' should have a 'logs' block defined", [resource_type, name]), - "keyActualValue": sprintf("'%s.%s' is missing the 'logs' block", [resource_type, name]), - } -} - -# RULE 2: The 'logs' block exists but does not have 'http_logs' configured. -CxPolicy[result] { - doc := input.document[i] - resource_type := targets[t] - app := doc.resource[resource_type][name] - - app.logs - not app.logs.http_logs - - result := { - "documentId": doc.id, - "resourceType": resource_type, - "resourceName": tf_lib.get_resource_name(app, name), - "searchKey": sprintf("%s[%s].logs", [resource_type, name]), - "searchLine": common_lib.build_search_line(["resource", resource_type, name, "logs"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'%s.%s.logs' should have 'http_logs' configured", [resource_type, name]), - "keyActualValue": sprintf("'%s.%s.logs' is missing 'http_logs'", [resource_type, name]), - } -} From 706eb8441efcbb90e008c70540f9749f61b353d3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:34:12 +0100 Subject: [PATCH 830/900] chore: remove azure_app_service_http_logs_disabled (duplicate of PR #7991) --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json deleted file mode 100644 index 6ca904e2497..00000000000 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "72eb3dd8-6892-47d1-9965-a5682de9f4e7", - "queryName": "Beta - App Service HTTP Logs Disabled", - "severity": "MEDIUM", - "category": "Observability", - "descriptionText": "Ensures that HTTP logs are enabled for Azure App Services. HTTP logs provide records of HTTP requests to the web app, which are crucial for security monitoring and debugging.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_web_app#http_logs", - "platform": "Terraform", - "descriptionID": "72eb3dd8", - "cloudProvider": "azure", - "cwe": "778", - "riskScore": "3.0", - "experimental": "true" -} \ No newline at end of file From a1409ecff7ff2e37f399de3057064ed30c83a269 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:34:12 +0100 Subject: [PATCH 831/900] chore: remove azure_app_service_http_logs_disabled (duplicate of PR #7991) --- .../test/positive1.tf | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive1.tf diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive1.tf deleted file mode 100644 index e797b245c24..00000000000 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive1.tf +++ /dev/null @@ -1,8 +0,0 @@ -resource "azurerm_linux_web_app" "fail_no_logs" { - name = "app-fail-1" - resource_group_name = "rg" - location = "West Europe" - service_plan_id = "plan-id" - - site_config {} -} \ No newline at end of file From ca4be06bce9b6044c2e19b0426209d1eab85a828 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:34:13 +0100 Subject: [PATCH 832/900] chore: remove azure_app_service_http_logs_disabled (duplicate of PR #7991) --- .../test/positive2.tf | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive2.tf diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive2.tf deleted file mode 100644 index 4e777bb67b8..00000000000 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive2.tf +++ /dev/null @@ -1,13 +0,0 @@ -resource "azurerm_windows_web_app" "fail_incomplete_logs" { - name = "app-fail-2" - resource_group_name = "rg" - location = "West Europe" - service_plan_id = "plan-id" - - logs { - application_logs { - file_system_level = "Information" - } - # Missing http_logs - } -} \ No newline at end of file From a4a898160af79e28cfd2f1d9ce215994a8c8079b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:34:14 +0100 Subject: [PATCH 833/900] chore: remove azure_app_service_http_logs_disabled (duplicate of PR #7991) --- .../test/negative1.tf | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/negative1.tf diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/negative1.tf b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/negative1.tf deleted file mode 100644 index 5b6ce2ddf69..00000000000 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/negative1.tf +++ /dev/null @@ -1,15 +0,0 @@ -resource "azurerm_linux_web_app" "pass_app" { - name = "app-pass" - resource_group_name = "rg" - location = "West Europe" - service_plan_id = "plan-id" - - logs { - http_logs { - file_system { - retention_in_days = 7 - retention_in_mb = 35 - } - } - } -} \ No newline at end of file From d4c7651bb831565fe82443d9db224e0b47c0477d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:34:14 +0100 Subject: [PATCH 834/900] chore: remove azure_app_service_http_logs_disabled (duplicate of PR #7991) --- .../test/positive_expected_result.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive_expected_result.json diff --git a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive_expected_result.json deleted file mode 100644 index ac98db21878..00000000000 --- a/assets/queries/terraform/azure/azure_app_service_http_logs_disabled/test/positive_expected_result.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "queryName": "Beta - App Service HTTP Logs Disabled", - "severity": "MEDIUM", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Beta - App Service HTTP Logs Disabled", - "severity": "MEDIUM", - "line": 7, - "fileName": "positive2.tf" - } -] From 8d667151e212de4c852097e65a4c29b5982d2269 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:38:04 +0100 Subject: [PATCH 835/900] fix: gate cross_region_restore rules on GeoRedundant redundancy --- .../query.rego | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego index 0531bebbaac..9439840bb7e 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/query.rego @@ -3,12 +3,14 @@ package Cx import data.generic.common as common_lib import data.generic.terraform as tf_lib -# RULE 1: Missing Configuration. +# RULE 1: Vault redundancy is GeoRedundant but 'cross_region_restore_enabled' is not defined. +# The attribute defaults to false when absent; it is only applicable to GeoRedundant vaults. CxPolicy[result] { doc := input.document[i] vault := doc.resource.azurerm_data_protection_backup_vault[name] - object.get(vault, "cross_region_restore_enabled", "undefined") == "undefined" + vault.redundancy == "GeoRedundant" + object.get(vault, "cross_region_restore_enabled", null) == null result := { "documentId": doc.id, @@ -17,16 +19,17 @@ CxPolicy[result] { "searchKey": sprintf("azurerm_data_protection_backup_vault[%s]", [name]), "searchLine": common_lib.build_search_line(["resource", "azurerm_data_protection_backup_vault", name], []), "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should have 'cross_region_restore_enabled' set to true", [name]), - "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is missing 'cross_region_restore_enabled'", [name]), + "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should have 'cross_region_restore_enabled' set to true when 'redundancy' is 'GeoRedundant'", [name]), + "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is missing 'cross_region_restore_enabled' (defaults to false)", [name]), } } -# RULE 2: Incorrect Configuration (Explicitly disabled). +# RULE 2: Vault redundancy is GeoRedundant but 'cross_region_restore_enabled' is explicitly false. CxPolicy[result] { doc := input.document[i] vault := doc.resource.azurerm_data_protection_backup_vault[name] + vault.redundancy == "GeoRedundant" vault.cross_region_restore_enabled == false result := { @@ -36,7 +39,7 @@ CxPolicy[result] { "searchKey": sprintf("azurerm_data_protection_backup_vault[%s].cross_region_restore_enabled", [name]), "searchLine": common_lib.build_search_line(["resource", "azurerm_data_protection_backup_vault", name, "cross_region_restore_enabled"], []), "issueType": "IncorrectValue", - "keyExpectedValue": "'cross_region_restore_enabled' should be set to true", - "keyActualValue": "'cross_region_restore_enabled' is set to false", + "keyExpectedValue": "'cross_region_restore_enabled' should be set to true when 'redundancy' is 'GeoRedundant'", + "keyActualValue": "'cross_region_restore_enabled' is explicitly set to false", } } From f9abe5b28e7d05926dd0038fe6d8a71d5a2c4c1e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:38:05 +0100 Subject: [PATCH 836/900] chore: fix inline Spanish comment in positive2.tf --- .../test/positive2.tf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive2.tf index 8a9cf10f0da..4291a252752 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive2.tf +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/positive2.tf @@ -1,9 +1,9 @@ -resource "azurerm_data_protection_backup_vault" "fail_explicit" { - name = "vault-disabled-crr" - resource_group_name = "rg-test" - location = "West Europe" - datastore_type = "VaultStore" - redundancy = "GeoRedundant" - - cross_region_restore_enabled = false # FALLO -} \ No newline at end of file +resource "azurerm_data_protection_backup_vault" "fail_explicit" { + name = "vault-disabled-crr" + resource_group_name = "rg-test" + location = "West Europe" + datastore_type = "VaultStore" + redundancy = "GeoRedundant" + + cross_region_restore_enabled = false # FAIL +} From 1df462335f939b8a8596bb2643e1e7d6b128c222 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:38:06 +0100 Subject: [PATCH 837/900] test: add negative case for LocallyRedundant vault (CRR not applicable) --- .../test/negative2.tf | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/negative2.tf diff --git a/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/negative2.tf b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/negative2.tf new file mode 100644 index 00000000000..a02fd159688 --- /dev/null +++ b/assets/queries/terraform/azure/azure_backup_vault_cross_region_restore_disabled/test/negative2.tf @@ -0,0 +1,8 @@ +# PASS: LocallyRedundant vault — cross_region_restore_enabled is not applicable +resource "azurerm_data_protection_backup_vault" "pass_local_redundant" { + name = "vault-local-redundant" + resource_group_name = "rg-test" + location = "West Europe" + datastore_type = "VaultStore" + redundancy = "LocallyRedundant" +} From ca25143ffe7d0639938d858ace8f028c9ed7f6de Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:41:41 +0100 Subject: [PATCH 838/900] fix: rename query to Backup Vault Managed Identity Not Configured; align description with identity/CMK check --- .../metadata.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json index 620cbfebaec..e0750921ce6 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/metadata.json @@ -1,9 +1,9 @@ { "id": "f7bf03d5-ae0e-4b36-aab3-f8d2346a8843", - "queryName": "Beta - Backup Vault Infrastructure Encryption Disabled", + "queryName": "Beta - Backup Vault Managed Identity Not Configured", "severity": "MEDIUM", "category": "Encryption", - "descriptionText": "Ensures that Azure Backup Vaults have a managed identity configured. A managed identity is required to support advanced encryption features including customer-managed keys (CMK) and infrastructure encryption.", + "descriptionText": "Ensures that Azure Backup Vaults have a managed identity configured. The 'identity' block is required to enable Customer-Managed Keys (CMK) for vault encryption. Without it, the vault relies solely on Microsoft-managed platform encryption, removing customer control over key lifecycle and rotation.", "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/data_protection_backup_vault#identity", "platform": "Terraform", "descriptionID": "f7bf03d5", @@ -11,4 +11,4 @@ "cwe": "312", "riskScore": "3.0", "experimental": "true" -} \ No newline at end of file +} From d4a7be209068231761d739abeddccbd4f2f18632 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:41:42 +0100 Subject: [PATCH 839/900] fix: update rule comment and result messages to reflect identity/CMK context --- .../query.rego | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego index 8eeb0bfc9b2..3bc8deb84a4 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/query.rego @@ -3,7 +3,9 @@ package Cx import data.generic.common as common_lib import data.generic.terraform as tf_lib -# RULE 1: The 'identity' block is missing, which is required to manage advanced encryption. +# RULE 1: The 'identity' block is absent, preventing Customer-Managed Key (CMK) encryption. +# Without a managed identity the vault is limited to Microsoft-managed platform encryption, +# removing customer control over key lifecycle and rotation. CxPolicy[result] { doc := input.document[i] vault := doc.resource.azurerm_data_protection_backup_vault[name] @@ -17,7 +19,7 @@ CxPolicy[result] { "searchKey": sprintf("azurerm_data_protection_backup_vault[%s]", [name]), "searchLine": common_lib.build_search_line(["resource", "azurerm_data_protection_backup_vault", name], []), "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should have an 'identity' block to support advanced encryption", [name]), - "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is missing the 'identity' block", [name]), + "keyExpectedValue": sprintf("'azurerm_data_protection_backup_vault.%s' should have an 'identity' block to enable Customer-Managed Key (CMK) encryption", [name]), + "keyActualValue": sprintf("'azurerm_data_protection_backup_vault.%s' is missing the 'identity' block; vault uses Microsoft-managed platform encryption only", [name]), } } From 0f42234a8747a49dbc3c3c945b47c14d45cb0426 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:41:42 +0100 Subject: [PATCH 840/900] chore: translate Spanish comment to English in positive1.tf --- .../test/positive1.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive1.tf b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive1.tf index 2db240d4874..d57a662820e 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive1.tf +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive1.tf @@ -4,5 +4,5 @@ resource "azurerm_data_protection_backup_vault" "fail" { location = "West Europe" datastore_type = "VaultStore" redundancy = "LocallyRedundant" - # FAIL: No tiene bloque identity -} \ No newline at end of file + # FAIL: Missing identity block +} From 2d3c8f13b16cbfa706e2be61471b70c29808f333 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:41:43 +0100 Subject: [PATCH 841/900] test: update queryName in expected results to match renamed query --- .../test/positive_expected_result.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive_expected_result.json index cdf3aead85f..eb1392bfedc 100644 --- a/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_backup_vault_infrastructure_encryption_disabled/test/positive_expected_result.json @@ -1,6 +1,6 @@ [ { - "queryName": "Beta - Backup Vault Infrastructure Encryption Disabled", + "queryName": "Beta - Backup Vault Managed Identity Not Configured", "severity": "MEDIUM", "line": 1, "fileName": "positive1.tf" From 90597b8d5dd315a1253ee85939d2985451816259 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:45:04 +0100 Subject: [PATCH 842/900] fix: add Rule 2 checking Bastion ip_configuration presence; document scope limitation --- .../azure_bastion_host_missing/query.rego | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego b/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego index 480eae7dc53..b46bf4f8d53 100644 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/query.rego @@ -3,15 +3,15 @@ package Cx import data.generic.common as common_lib import data.generic.terraform as tf_lib -# RULE 1: A VNet exists, but no azurerm_bastion_host resource exists in the document. +# RULE 1: A VNet exists but no azurerm_bastion_host is declared in the same document. +# Note: this is a document-level check; Bastion association to a specific VNet subnet +# cannot be verified without cross-resource reference resolution. CxPolicy[result] { doc := input.document[i] vnet := doc.resource.azurerm_virtual_network[name] - bastions := [b | b := doc.resource.azurerm_bastion_host[_]] - - count(bastions) == 0 + count([b | b := doc.resource.azurerm_bastion_host[_]]) == 0 result := { "documentId": doc.id, @@ -24,3 +24,24 @@ CxPolicy[result] { "keyActualValue": "No 'azurerm_bastion_host' resource was found in the configuration", } } + +# RULE 2: An azurerm_bastion_host is declared but missing the required ip_configuration block. +# ip_configuration is mandatory in the Terraform schema and must reference a dedicated +# subnet named 'AzureBastionSubnet' and a Standard-tier public IP address. +CxPolicy[result] { + doc := input.document[i] + + bastion := doc.resource.azurerm_bastion_host[name] + not bastion.ip_configuration + + result := { + "documentId": doc.id, + "resourceType": "azurerm_bastion_host", + "resourceName": tf_lib.get_resource_name(bastion, name), + "searchKey": sprintf("azurerm_bastion_host[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_bastion_host", name], []), + "issueType": "MissingAttribute", + "keyExpectedValue": sprintf("'azurerm_bastion_host.%s' should have an 'ip_configuration' block referencing an 'AzureBastionSubnet' subnet", [name]), + "keyActualValue": sprintf("'azurerm_bastion_host.%s' is missing the required 'ip_configuration' block", [name]), + } +} From f6a94789fb806cbc13b3a8e3bbc37fccd2e3e86c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:45:04 +0100 Subject: [PATCH 843/900] docs: expand description to cover ip_configuration requirement and scope limitation --- .../terraform/azure/azure_bastion_host_missing/metadata.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json b/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json index 53090737c46..fc194c9a38c 100644 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json @@ -3,7 +3,7 @@ "queryName": "Beta - Azure Bastion Host Missing", "severity": "MEDIUM", "category": "Networking and Firewall", - "descriptionText": "Ensures that an Azure Bastion Host is present when Virtual Networks are defined. Azure Bastion provides secure and seamless RDP/SSH connectivity to your virtual machines directly from the Azure portal over SSL.", + "descriptionText": "Ensures that Azure Virtual Networks are protected by a Bastion Host and that the Bastion Host has a valid ip_configuration block. Azure Bastion provides secure RDP/SSH access to virtual machines without exposing them to the public internet. A complete Bastion setup requires an azurerm_bastion_host with an ip_configuration referencing a dedicated subnet named AzureBastionSubnet and a Standard-tier public IP. Note: this query verifies resource presence at the document level; subnet-level association between the Bastion and a specific VNet is not verified.", "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/bastion_host", "platform": "Terraform", "descriptionID": "a3e941c5", @@ -11,4 +11,4 @@ "cwe": "284", "riskScore": "3.0", "experimental": "true" -} \ No newline at end of file +} From b091cd22369517879fbfc51127357f2e5ce5257c Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:45:05 +0100 Subject: [PATCH 844/900] test: add positive case for Bastion without ip_configuration block --- .../azure/azure_bastion_host_missing/test/positive2.tf | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 assets/queries/terraform/azure/azure_bastion_host_missing/test/positive2.tf diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive2.tf b/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive2.tf new file mode 100644 index 00000000000..ff716f48445 --- /dev/null +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive2.tf @@ -0,0 +1,6 @@ +resource "azurerm_bastion_host" "fail_no_ip_config" { + name = "bastion-incomplete" + location = "West Europe" + resource_group_name = "rg-test" + # FAIL: Missing required ip_configuration block +} From 6c59e2161d52e23d7b42b828161779d44ec0aa0a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 22:45:06 +0100 Subject: [PATCH 845/900] test: add positive2.tf to expected results --- .../test/positive_expected_result.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive_expected_result.json index 9d20dd2ef7a..98256c5a43c 100644 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/test/positive_expected_result.json @@ -4,5 +4,11 @@ "severity": "MEDIUM", "line": 1, "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Azure Bastion Host Missing", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive2.tf" } ] From 57fa41459db4e46cb6a6456af21fc07e13cbf092 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:02:57 +0100 Subject: [PATCH 846/900] fix: rename to Elastic SAN Volume Group Network Rules Not Configured; clarify SAN vs volume group distinction --- .../azure_elastic_san_public_access_enabled/metadata.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json index af6f12884af..fe022f2df7f 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/metadata.json @@ -1,9 +1,9 @@ { "id": "660863a5-bb45-4907-8afe-d7478177a446", - "queryName": "Beta - Elastic SAN Public Network Access Enabled", + "queryName": "Beta - Elastic SAN Volume Group Network Rules Not Configured", "severity": "HIGH", "category": "Networking and Firewall", - "descriptionText": "Ensures that Azure Elastic SAN Volume Groups have network rules configured to restrict public network access to approved virtual networks only. Volume groups without a network_rule block allow unrestricted public access to storage volumes.", + "descriptionText": "Ensures that Azure Elastic SAN Volume Groups have network rules configured to restrict access to approved virtual networks only. The network_rule block defines a whitelist of subnets permitted to access the volume group; without it, no subnet-level access restriction is applied. Note: public_network_access_enabled is a separate attribute on azurerm_elastic_san (the SAN resource itself) and controls network access at the SAN level.", "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/elastic_san_volume_group#network_rule", "platform": "Terraform", "cloudProvider": "azure", @@ -11,4 +11,4 @@ "descriptionID": "660863a5", "riskScore": "6.0", "experimental": "true" -} \ No newline at end of file +} From 9f1b9d3cbaf957cc914df9ed838214a797a05b8a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:02:58 +0100 Subject: [PATCH 847/900] fix: update comment to clarify network_rule scope and public_network_access_enabled distinction --- .../query.rego | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego index 0474507405e..6f8f91cae8d 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/query.rego @@ -3,8 +3,11 @@ package Cx import data.generic.common as common_lib import data.generic.terraform as tf_lib -# RULE 1: The 'network_rule' block is not defined. -# In azurerm_elastic_san_volume_group, the absence of the block allows public access. +# RULE 1: The 'network_rule' block is missing from an azurerm_elastic_san_volume_group. +# network_rule defines a subnet whitelist; its absence means no subnet-level access +# restriction is applied to the volume group. +# Note: public_network_access_enabled is a separate attribute on azurerm_elastic_san +# (the SAN resource itself) and is not present on azurerm_elastic_san_volume_group. CxPolicy[result] { doc := input.document[i] vg := doc.resource.azurerm_elastic_san_volume_group[name] @@ -18,7 +21,7 @@ CxPolicy[result] { "searchKey": sprintf("azurerm_elastic_san_volume_group[%s]", [name]), "searchLine": common_lib.build_search_line(["resource", "azurerm_elastic_san_volume_group", name], []), "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_elastic_san_volume_group.%s' should have a 'network_rule' block to restrict public access", [name]), - "keyActualValue": sprintf("'azurerm_elastic_san_volume_group.%s' is missing the 'network_rule' block", [name]), + "keyExpectedValue": sprintf("'azurerm_elastic_san_volume_group.%s' should have a 'network_rule' block to restrict access to approved subnets only", [name]), + "keyActualValue": sprintf("'azurerm_elastic_san_volume_group.%s' has no 'network_rule' block; no subnet-level access restriction is applied", [name]), } } From f19ce5a49e27da1fef2267d41bcd7a8b70609a29 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:02:59 +0100 Subject: [PATCH 848/900] chore: translate Spanish comment to English in positive1.tf --- .../test/positive1.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive1.tf b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive1.tf index f03f3c5de58..d579f9af843 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive1.tf +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive1.tf @@ -1,5 +1,5 @@ -resource "azurerm_elastic_san_volume_group" "fail" { - name = "insecure-vg" - elastic_san_id = "san-id" - # Falla por no tener network_rule -} \ No newline at end of file +resource "azurerm_elastic_san_volume_group" "fail" { + name = "insecure-vg" + elastic_san_id = "san-id" + # FAIL: Missing network_rule block +} From 7bb98a858dcc1e455766832cabc8469706d5779f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:02:59 +0100 Subject: [PATCH 849/900] test: update queryName in expected results to match renamed query --- .../test/positive_expected_result.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive_expected_result.json index e782d3b36aa..669a653127c 100644 --- a/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_elastic_san_public_access_enabled/test/positive_expected_result.json @@ -1,6 +1,6 @@ [ { - "queryName": "Beta - Elastic SAN Public Network Access Enabled", + "queryName": "Beta - Elastic SAN Volume Group Network Rules Not Configured", "severity": "HIGH", "line": 1, "fileName": "positive1.tf" From 8a07e9f8753b60bbbeb7412dd21878cd7e9069a2 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:05:45 +0100 Subject: [PATCH 850/900] fix: add Rule 2 for security solution with enabled=false --- .../query.rego | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego index b6b40288bc7..ec49f0a99bf 100644 --- a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/query.rego @@ -3,20 +3,18 @@ package Cx import data.generic.common as common_lib import data.generic.terraform as tf_lib -# RULE 1: IoT Hub without an associated security solution (azurerm_iot_security_solution). +# RULE 1: IoT Hub has no associated azurerm_iot_security_solution. +# Checked at document level via iothub_ids reference matching. CxPolicy[result] { doc := input.document[i] iot_hub := doc.resource.azurerm_iothub[hub_name] hub_ref := sprintf("azurerm_iothub.%s.id", [hub_name]) - solutions := [sol | + count([sol | sol := doc.resource.azurerm_iot_security_solution[_] - current_hub_id := sol.iothub_ids[_] - check_hub_id(current_hub_id, hub_ref) - ] - - count(solutions) == 0 + check_hub_id(sol.iothub_ids[_], hub_ref) + ]) == 0 result := { "documentId": doc.id, @@ -30,6 +28,31 @@ CxPolicy[result] { } } +# RULE 2: IoT Hub has an associated security solution but it is explicitly disabled. +# azurerm_iot_security_solution.enabled defaults to true; setting it to false disables +# Defender for IoT while leaving the resource declared in the configuration. +CxPolicy[result] { + doc := input.document[i] + iot_hub := doc.resource.azurerm_iothub[hub_name] + + hub_ref := sprintf("azurerm_iothub.%s.id", [hub_name]) + + sol := doc.resource.azurerm_iot_security_solution[sol_name] + check_hub_id(sol.iothub_ids[_], hub_ref) + sol.enabled == false + + result := { + "documentId": doc.id, + "resourceType": "azurerm_iot_security_solution", + "resourceName": tf_lib.get_resource_name(sol, sol_name), + "searchKey": sprintf("azurerm_iot_security_solution[%s].enabled", [sol_name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_iot_security_solution", sol_name, "enabled"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": sprintf("'azurerm_iot_security_solution.%s' should have 'enabled' set to true", [sol_name]), + "keyActualValue": sprintf("'azurerm_iot_security_solution.%s' has 'enabled' explicitly set to false", [sol_name]), + } +} + check_hub_id(current, target) { current == target } From 384756841927ab0551fb010a1160afe393957925 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:05:46 +0100 Subject: [PATCH 851/900] test: add positive case for security solution with enabled=false --- .../test/positive2.tf | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive2.tf diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive2.tf b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive2.tf new file mode 100644 index 00000000000..3f8660c043e --- /dev/null +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive2.tf @@ -0,0 +1,19 @@ +resource "azurerm_iothub" "fail_disabled" { + name = "example-iothub-fail-disabled" + resource_group_name = "rg-test" + location = "West Europe" + + sku { + name = "S1" + capacity = "1" + } +} + +resource "azurerm_iot_security_solution" "fail_disabled" { + name = "example-security-solution-disabled" + resource_group_name = "rg-test" + location = "West Europe" + display_name = "Iot Security Solution" + iothub_ids = [azurerm_iothub.fail_disabled.id] + enabled = false +} From ada64131715c53a3f488063e5d1abb337d69040b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:05:47 +0100 Subject: [PATCH 852/900] test: add positive2.tf result for disabled security solution --- .../test/positive_expected_result.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive_expected_result.json index c4952e6c3a5..1ff1d0ff6b6 100644 --- a/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_iot_hub_defender_disabled/test/positive_expected_result.json @@ -4,5 +4,11 @@ "severity": "MEDIUM", "line": 1, "fileName": "positive1.tf" + }, + { + "queryName": "Beta - Azure IoT Hub Defender Disabled", + "severity": "MEDIUM", + "line": 18, + "fileName": "positive2.tf" } ] From 99d9b9ac53ac3cd8300fefdeb929de944de2bffc Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:08:39 +0100 Subject: [PATCH 853/900] fix: replace broken Registry anchor with Azure CMK docs URL; clarify encryption_key source in description --- .../metadata.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json index 01d30de188a..ddc5845c943 100644 --- a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/metadata.json @@ -3,12 +3,12 @@ "queryName": "Beta - Azure Managed Lustre Not Encrypted with CMK", "severity": "MEDIUM", "category": "Encryption", - "descriptionText": "Ensures that Azure Managed Lustre file systems are encrypted using a Customer-Managed Key (CMK). By default, data is encrypted with platform-managed keys, but CMK provides full control over key rotation and access policies.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/managed_lustre_file_system#encryption_key", + "descriptionText": "Ensures that Azure Managed Lustre file systems are encrypted using a Customer-Managed Key (CMK) via the 'encryption_key' block. By default, data is encrypted with platform-managed keys; CMK provides full control over key lifecycle and access policies. The 'encryption_key' block is documented in the azurerm provider source and requires 'key_url' (Key Vault key URL) and 'source_vault_id' (Key Vault resource ID).", + "descriptionUrl": "https://learn.microsoft.com/en-us/azure/azure-managed-lustre/customer-managed-encryption-keys", "platform": "Terraform", "cloudProvider": "azure", "cwe": "326", "descriptionID": "7fc653e2", "riskScore": "3.0", "experimental": "true" -} \ No newline at end of file +} From cca560f79d69f803dd26cd3b74a3bcd75390047e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:08:39 +0100 Subject: [PATCH 854/900] docs: add provider source reference to encryption_key comment for traceability --- .../query.rego | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego index 9ca2ed4889b..1a59490463c 100644 --- a/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_managed_lustre_cmk_encryption_disabled/query.rego @@ -4,6 +4,11 @@ import data.generic.common as common_lib import data.generic.terraform as tf_lib # RULE 1: The 'encryption_key' block is not defined. +# 'encryption_key' is an optional block on azurerm_managed_lustre_file_system documented +# in the azurerm provider source. It requires: +# key_url - Key Vault key URL +# source_vault_id - Key Vault resource ID +# Reference: https://github.com/hashicorp/terraform-provider-azurerm/blob/main/website/docs/r/managed_lustre_file_system.html.markdown CxPolicy[result] { doc := input.document[i] lustre := doc.resource.azurerm_managed_lustre_file_system[name] @@ -17,7 +22,7 @@ CxPolicy[result] { "searchKey": sprintf("azurerm_managed_lustre_file_system[%s]", [name]), "searchLine": common_lib.build_search_line(["resource", "azurerm_managed_lustre_file_system", name], []), "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_managed_lustre_file_system.%s' should have an 'encryption_key' block defined", [name]), - "keyActualValue": sprintf("'azurerm_managed_lustre_file_system.%s' is missing the 'encryption_key' block", [name]), + "keyExpectedValue": sprintf("'azurerm_managed_lustre_file_system.%s' should have an 'encryption_key' block with 'key_url' and 'source_vault_id'", [name]), + "keyActualValue": sprintf("'azurerm_managed_lustre_file_system.%s' is missing the 'encryption_key' block; data is encrypted with platform-managed keys only", [name]), } } From 281538528d676da7776cdd06e2422f817d7e51bf Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:12:21 +0100 Subject: [PATCH 855/900] fix: remove azurerm_mssql_server from targets (MSSQL != MySQL); align key values with azurerm_mysql_flexible_server_configuration --- .../query.rego | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego index 1f4fd3ea815..ac869ce0a49 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego @@ -3,23 +3,23 @@ package Cx import data.generic.common as common_lib import data.generic.terraform as tf_lib -targets := {"azurerm_mssql_server", "azurerm_mysql_flexible_server"} - -# MANUAL RULE: Detects MySQL servers to request verification of the CONNECTION event. +# MANUAL CHECK: Flags azurerm_mysql_flexible_server resources for human review. +# The 'audit_log_events' parameter is not an attribute on azurerm_mysql_flexible_server +# itself; it must be set via a separate azurerm_mysql_flexible_server_configuration resource +# with name = "audit_log_events" and value containing "CONNECTION". +# This query cannot verify that configuration automatically and requires manual confirmation. CxPolicy[result] { doc := input.document[i] - - resource_type := targets[t] - server := doc.resource[resource_type][name] + server := doc.resource.azurerm_mysql_flexible_server[name] result := { "documentId": doc.id, - "resourceType": resource_type, + "resourceType": "azurerm_mysql_flexible_server", "resourceName": tf_lib.get_resource_name(server, name), - "searchKey": sprintf("%s[%s]", [resource_type, name]), - "searchLine": common_lib.build_search_line(["resource", resource_type, name], []), + "searchKey": sprintf("azurerm_mysql_flexible_server[%s]", [name]), + "searchLine": common_lib.build_search_line(["resource", "azurerm_mysql_flexible_server", name], []), "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'audit_log_events' should include 'CONNECTION' for '%s.%s' (Manual Verification)", [resource_type, name]), - "keyActualValue": "Audit log event configuration requires manual verification or check of 'azurerm_mysql_configuration'", + "keyExpectedValue": sprintf("'azurerm_mysql_flexible_server.%s' should have a paired 'azurerm_mysql_flexible_server_configuration' resource setting 'audit_log_events' to include 'CONNECTION'", [name]), + "keyActualValue": sprintf("'azurerm_mysql_flexible_server.%s' requires manual verification: confirm an 'azurerm_mysql_flexible_server_configuration' with name='audit_log_events' and value including 'CONNECTION' is present", [name]), } } From 79f4c48081a50bbed0d3a14aee55c2ce783471ea Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:12:21 +0100 Subject: [PATCH 856/900] fix: rewrite description to accurately reflect manual check intent and configuration path --- .../metadata.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json index c2915fda6fa..d85e437285a 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json @@ -3,12 +3,12 @@ "queryName": "Beta - MySQL Audit Log Events Connection (Manual)", "severity": "INFO", "category": "Observability", - "descriptionText": "Ensures that the 'audit_log_events' server parameter includes 'CONNECTION' for Azure MySQL Flexible Server and Azure SQL Server (MSSQL) instances, capturing successful and failed connection attempts. Manual verification is required.", - "descriptionUrl": "https://learn.microsoft.com/en-us/azure/mysql/single-server/concepts-audit-logs", + "descriptionText": "Flags Azure MySQL Flexible Server instances for manual verification that the 'audit_log_events' parameter includes 'CONNECTION'. This parameter is not a direct attribute on azurerm_mysql_flexible_server; it must be configured via a separate azurerm_mysql_flexible_server_configuration resource. Because the association between server and configuration cannot be automatically verified, this check requires manual confirmation.", + "descriptionUrl": "https://learn.microsoft.com/en-us/azure/mysql/flexible-server/concepts-audit-logs", "platform": "Terraform", "cloudProvider": "azure", "cwe": "778", "descriptionID": "fe65cd89", "riskScore": "0.0", "experimental": "true" -} \ No newline at end of file +} From 553333e2d3b2b7ea0cae07d8df96cfb6322acfc8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:12:22 +0100 Subject: [PATCH 857/900] fix: replace azurerm_mssql_server with azurerm_mysql_flexible_server in positive test --- .../test/positive1.tf | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive1.tf b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive1.tf index d406e50d290..d06ad4ec2e5 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive1.tf +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive1.tf @@ -1,8 +1,10 @@ -resource "azurerm_mssql_server" "fail_single" { - name = "mysql-server-connection-fail" - resource_group_name = "rg-test" - location = "West Europe" - administrator_login = "mysqladmin" - administrator_login_password = "Password1234!" - version = "5.7" -} \ No newline at end of file +resource "azurerm_mysql_flexible_server" "fail" { + name = "mysql-server-connection-fail" + resource_group_name = "rg-test" + location = "West Europe" + administrator_login = "mysqladmin" + administrator_login_password = "Password1234!" + sku_name = "GP_Standard_D2ds_v4" + version = "8.0.21" + # FAIL: No paired azurerm_mysql_flexible_server_configuration for audit_log_events +} From aede0f2c418dcca983191bb870fe52e9718f298a Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:12:23 +0100 Subject: [PATCH 858/900] fix: remove non-existent positive2.tf from expected results --- .../test/positive_expected_result.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json index 0c4e71fe8ea..37e918fc94c 100644 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json @@ -4,11 +4,5 @@ "severity": "INFO", "line": 1, "fileName": "positive1.tf" - }, - { - "queryName": "Beta - MySQL Audit Log Events Connection (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive2.tf" } ] From 780689cbe67141e82ee9531f7ea6305a4ecaf7ee Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:12:24 +0100 Subject: [PATCH 859/900] fix: remove dangling positive2.tf (no longer needed with single target type) --- .../test/positive2.tf | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive2.tf diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive2.tf b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive2.tf deleted file mode 100644 index f9529c2d915..00000000000 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive2.tf +++ /dev/null @@ -1,7 +0,0 @@ -resource "azurerm_mysql_flexible_server" "fail_flexible" { - name = "mysql-flex-server-connection-fail" - resource_group_name = "rg-test" - location = "West Europe" - administrator_login = "mysqladmin" - administrator_password = "Password1234!" -} \ No newline at end of file From f1ed1ae3e0915cbcc9bbed959ec3be18d2eb6e59 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:21:23 +0100 Subject: [PATCH 860/900] =?UTF-8?q?chore:=20remove=20azure=5Fmysql=5Faudit?= =?UTF-8?q?=5Flog=5Fenabled=5Fmanual=20(always-fire=20manual=20check=20?= =?UTF-8?q?=E2=80=94=20cannot=20verify=20audit=20config=20in=20IaC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../query.rego | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego deleted file mode 100644 index 60ea00e6b39..00000000000 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/query.rego +++ /dev/null @@ -1,25 +0,0 @@ -package Cx - -import data.generic.common as common_lib -import data.generic.terraform as tf_lib - -targets := {"azurerm_mssql_server", "azurerm_mysql_flexible_server"} - -# MANUAL RULE: Detects MySQL servers to request verification of audit logs. -CxPolicy[result] { - doc := input.document[i] - - resource_type := targets[t] - server := doc.resource[resource_type][name] - - result := { - "documentId": doc.id, - "resourceType": resource_type, - "resourceName": tf_lib.get_resource_name(server, name), - "searchKey": sprintf("%s[%s]", [resource_type, name]), - "searchLine": common_lib.build_search_line(["resource", resource_type, name], []), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'audit_log_enabled' should be set to 'ON' for '%s.%s' (Manual Verification)", [resource_type, name]), - "keyActualValue": "Logging configuration requires manual verification or check of 'azurerm_mysql_configuration' resources", - } -} From bb16b4e297393fc3093cacf08986dc85ae11b577 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:21:24 +0100 Subject: [PATCH 861/900] =?UTF-8?q?chore:=20remove=20azure=5Fmysql=5Faudit?= =?UTF-8?q?=5Flog=5Fenabled=5Fmanual=20(always-fire=20manual=20check=20?= =?UTF-8?q?=E2=80=94=20cannot=20verify=20audit=20config=20in=20IaC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json deleted file mode 100644 index 303681b40f8..00000000000 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "8d8ac482-16c2-4eb7-bfab-e2d94d035498", - "queryName": "Beta - MySQL Audit Log Enabled (Manual)", - "severity": "INFO", - "category": "Observability", - "descriptionText": "Ensures that audit logging is enabled for Azure MySQL Flexible Server and Azure SQL Server (MSSQL) instances. Since audit log settings are managed via server parameters outside Terraform, manual verification is required.", - "descriptionUrl": "https://learn.microsoft.com/en-us/azure/mysql/single-server/concepts-audit-logs", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "778", - "descriptionID": "8d8ac482", - "riskScore": "0.0", - "experimental": "true" -} \ No newline at end of file From 34162dac209a83a58a1f18b6865b7b2bb218822e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:21:25 +0100 Subject: [PATCH 862/900] =?UTF-8?q?chore:=20remove=20azure=5Fmysql=5Faudit?= =?UTF-8?q?=5Flog=5Fenabled=5Fmanual=20(always-fire=20manual=20check=20?= =?UTF-8?q?=E2=80=94=20cannot=20verify=20audit=20config=20in=20IaC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/positive1.tf | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive1.tf diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive1.tf b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive1.tf deleted file mode 100644 index 98f95c296a0..00000000000 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive1.tf +++ /dev/null @@ -1,8 +0,0 @@ -resource "azurerm_mssql_server" "fail_single" { - name = "mysql-server-1" - resource_group_name = "rg-test" - location = "West Europe" - administrator_login = "mysqladmin" - administrator_login_password = "Password1234!" - version = "5.7" -} \ No newline at end of file From bbca055d34cb916dfe0c5aae059ad56bdeab0bc8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:21:26 +0100 Subject: [PATCH 863/900] =?UTF-8?q?chore:=20remove=20azure=5Fmysql=5Faudit?= =?UTF-8?q?=5Flog=5Fenabled=5Fmanual=20(always-fire=20manual=20check=20?= =?UTF-8?q?=E2=80=94=20cannot=20verify=20audit=20config=20in=20IaC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../azure_mysql_audit_log_enabled_manual/test/positive2.tf | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive2.tf diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive2.tf b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive2.tf deleted file mode 100644 index 9cdb9785156..00000000000 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive2.tf +++ /dev/null @@ -1,7 +0,0 @@ -resource "azurerm_mysql_flexible_server" "fail_flexible" { - name = "mysql-flex-server-1" - resource_group_name = "rg-test" - location = "West Europe" - administrator_login = "mysqladmin" - administrator_password = "Password1234!" -} \ No newline at end of file From 6b4142eda4439e5df23f027fe13680c54d83086d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:21:27 +0100 Subject: [PATCH 864/900] =?UTF-8?q?chore:=20remove=20azure=5Fmysql=5Faudit?= =?UTF-8?q?=5Flog=5Fenabled=5Fmanual=20(always-fire=20manual=20check=20?= =?UTF-8?q?=E2=80=94=20cannot=20verify=20audit=20config=20in=20IaC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../azure_mysql_audit_log_enabled_manual/test/negative1.tf | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/negative1.tf diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/negative1.tf b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/negative1.tf deleted file mode 100644 index b1137217038..00000000000 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/negative1.tf +++ /dev/null @@ -1,7 +0,0 @@ -resource "azurerm_storage_account" "no_mysql_here" { - name = "storageaccountneg1" - resource_group_name = "rg-test" - location = "West Europe" - account_tier = "Standard" - account_replication_type = "LRS" -} From 9caa4cdeed107fb465cd1e6d1b36a70a2281cd20 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:21:28 +0100 Subject: [PATCH 865/900] =?UTF-8?q?chore:=20remove=20azure=5Fmysql=5Faudit?= =?UTF-8?q?=5Flog=5Fenabled=5Fmanual=20(always-fire=20manual=20check=20?= =?UTF-8?q?=E2=80=94=20cannot=20verify=20audit=20config=20in=20IaC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/positive_expected_result.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive_expected_result.json diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive_expected_result.json deleted file mode 100644 index 831f402432a..00000000000 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_enabled_manual/test/positive_expected_result.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "queryName": "Beta - MySQL Audit Log Enabled (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - }, - { - "queryName": "Beta - MySQL Audit Log Enabled (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive2.tf" - } -] From 29403fa3371846280a4cacacdf99f0ead0942438 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:21:29 +0100 Subject: [PATCH 866/900] =?UTF-8?q?chore:=20remove=20azure=5Fmysql=5Faudit?= =?UTF-8?q?=5Flog=5Fevents=5Fconnection=5Fmanual=20(always-fire=20manual?= =?UTF-8?q?=20check=20=E2=80=94=20cannot=20verify=20audit=20config=20in=20?= =?UTF-8?q?IaC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../query.rego | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego deleted file mode 100644 index ac869ce0a49..00000000000 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/query.rego +++ /dev/null @@ -1,25 +0,0 @@ -package Cx - -import data.generic.common as common_lib -import data.generic.terraform as tf_lib - -# MANUAL CHECK: Flags azurerm_mysql_flexible_server resources for human review. -# The 'audit_log_events' parameter is not an attribute on azurerm_mysql_flexible_server -# itself; it must be set via a separate azurerm_mysql_flexible_server_configuration resource -# with name = "audit_log_events" and value containing "CONNECTION". -# This query cannot verify that configuration automatically and requires manual confirmation. -CxPolicy[result] { - doc := input.document[i] - server := doc.resource.azurerm_mysql_flexible_server[name] - - result := { - "documentId": doc.id, - "resourceType": "azurerm_mysql_flexible_server", - "resourceName": tf_lib.get_resource_name(server, name), - "searchKey": sprintf("azurerm_mysql_flexible_server[%s]", [name]), - "searchLine": common_lib.build_search_line(["resource", "azurerm_mysql_flexible_server", name], []), - "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_mysql_flexible_server.%s' should have a paired 'azurerm_mysql_flexible_server_configuration' resource setting 'audit_log_events' to include 'CONNECTION'", [name]), - "keyActualValue": sprintf("'azurerm_mysql_flexible_server.%s' requires manual verification: confirm an 'azurerm_mysql_flexible_server_configuration' with name='audit_log_events' and value including 'CONNECTION' is present", [name]), - } -} From 4da02e2c82fec30de36567ddbd23c2d4d8083838 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:21:30 +0100 Subject: [PATCH 867/900] =?UTF-8?q?chore:=20remove=20azure=5Fmysql=5Faudit?= =?UTF-8?q?=5Flog=5Fevents=5Fconnection=5Fmanual=20(always-fire=20manual?= =?UTF-8?q?=20check=20=E2=80=94=20cannot=20verify=20audit=20config=20in=20?= =?UTF-8?q?IaC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metadata.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json deleted file mode 100644 index d85e437285a..00000000000 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/metadata.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "fe65cd89-28ea-4301-9c50-6dee30553557", - "queryName": "Beta - MySQL Audit Log Events Connection (Manual)", - "severity": "INFO", - "category": "Observability", - "descriptionText": "Flags Azure MySQL Flexible Server instances for manual verification that the 'audit_log_events' parameter includes 'CONNECTION'. This parameter is not a direct attribute on azurerm_mysql_flexible_server; it must be configured via a separate azurerm_mysql_flexible_server_configuration resource. Because the association between server and configuration cannot be automatically verified, this check requires manual confirmation.", - "descriptionUrl": "https://learn.microsoft.com/en-us/azure/mysql/flexible-server/concepts-audit-logs", - "platform": "Terraform", - "cloudProvider": "azure", - "cwe": "778", - "descriptionID": "fe65cd89", - "riskScore": "0.0", - "experimental": "true" -} From 1de7eb90a80b134253b108c76955a26cabcbbf12 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:21:30 +0100 Subject: [PATCH 868/900] =?UTF-8?q?chore:=20remove=20azure=5Fmysql=5Faudit?= =?UTF-8?q?=5Flog=5Fevents=5Fconnection=5Fmanual=20(always-fire=20manual?= =?UTF-8?q?=20check=20=E2=80=94=20cannot=20verify=20audit=20config=20in=20?= =?UTF-8?q?IaC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/positive1.tf | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive1.tf diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive1.tf b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive1.tf deleted file mode 100644 index d06ad4ec2e5..00000000000 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive1.tf +++ /dev/null @@ -1,10 +0,0 @@ -resource "azurerm_mysql_flexible_server" "fail" { - name = "mysql-server-connection-fail" - resource_group_name = "rg-test" - location = "West Europe" - administrator_login = "mysqladmin" - administrator_login_password = "Password1234!" - sku_name = "GP_Standard_D2ds_v4" - version = "8.0.21" - # FAIL: No paired azurerm_mysql_flexible_server_configuration for audit_log_events -} From b549e0e37fd113baa37aa2f9191fd3f5f74721e0 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:21:31 +0100 Subject: [PATCH 869/900] =?UTF-8?q?chore:=20remove=20azure=5Fmysql=5Faudit?= =?UTF-8?q?=5Flog=5Fevents=5Fconnection=5Fmanual=20(always-fire=20manual?= =?UTF-8?q?=20check=20=E2=80=94=20cannot=20verify=20audit=20config=20in=20?= =?UTF-8?q?IaC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/negative1.tf | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/negative1.tf diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/negative1.tf b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/negative1.tf deleted file mode 100644 index b1137217038..00000000000 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/negative1.tf +++ /dev/null @@ -1,7 +0,0 @@ -resource "azurerm_storage_account" "no_mysql_here" { - name = "storageaccountneg1" - resource_group_name = "rg-test" - location = "West Europe" - account_tier = "Standard" - account_replication_type = "LRS" -} From 4ad2844a49961b6d0d7427396abd3309c7281945 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:21:32 +0100 Subject: [PATCH 870/900] =?UTF-8?q?chore:=20remove=20azure=5Fmysql=5Faudit?= =?UTF-8?q?=5Flog=5Fevents=5Fconnection=5Fmanual=20(always-fire=20manual?= =?UTF-8?q?=20check=20=E2=80=94=20cannot=20verify=20audit=20config=20in=20?= =?UTF-8?q?IaC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/positive_expected_result.json | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json diff --git a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json deleted file mode 100644 index 37e918fc94c..00000000000 --- a/assets/queries/terraform/azure/azure_mysql_audit_log_events_connection_manual/test/positive_expected_result.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "queryName": "Beta - MySQL Audit Log Events Connection (Manual)", - "severity": "INFO", - "line": 1, - "fileName": "positive1.tf" - } -] From 038c4fbf7ba25563b81f4928cb420cd896e4fbff Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:22:20 +0100 Subject: [PATCH 871/900] fix: gate cross_region_restore rules on GeoRedundant storage_mode_type (mirrors backup vault fix) --- .../query.rego | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego index 62945cc7fc4..1dd57e477b0 100644 --- a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/query.rego @@ -3,12 +3,15 @@ package Cx import data.generic.common as common_lib import data.generic.terraform as tf_lib -# RULE 1: The 'cross_region_restore_enabled' attribute is missing. +# RULE 1: Vault storage_mode_type is GeoRedundant but 'cross_region_restore_enabled' is not defined. +# cross_region_restore_enabled can only be enabled when storage_mode_type is GeoRedundant; +# when absent it defaults to false. CxPolicy[result] { doc := input.document[i] vault := doc.resource.azurerm_recovery_services_vault[name] - object.get(vault, "cross_region_restore_enabled", "undefined") == "undefined" + vault.storage_mode_type == "GeoRedundant" + object.get(vault, "cross_region_restore_enabled", null) == null result := { "documentId": doc.id, @@ -17,16 +20,17 @@ CxPolicy[result] { "searchKey": sprintf("azurerm_recovery_services_vault[%s]", [name]), "searchLine": common_lib.build_search_line(["resource", "azurerm_recovery_services_vault", name], []), "issueType": "MissingAttribute", - "keyExpectedValue": sprintf("'azurerm_recovery_services_vault.%s' should have 'cross_region_restore_enabled' set to true", [name]), - "keyActualValue": sprintf("'azurerm_recovery_services_vault.%s' is missing 'cross_region_restore_enabled'", [name]), + "keyExpectedValue": sprintf("'azurerm_recovery_services_vault.%s' should have 'cross_region_restore_enabled' set to true when 'storage_mode_type' is 'GeoRedundant'", [name]), + "keyActualValue": sprintf("'azurerm_recovery_services_vault.%s' is missing 'cross_region_restore_enabled' (defaults to false)", [name]), } } -# RULE 2: The 'cross_region_restore_enabled' attribute is set to false. +# RULE 2: Vault storage_mode_type is GeoRedundant but 'cross_region_restore_enabled' is explicitly false. CxPolicy[result] { doc := input.document[i] vault := doc.resource.azurerm_recovery_services_vault[name] + vault.storage_mode_type == "GeoRedundant" vault.cross_region_restore_enabled == false result := { @@ -36,7 +40,7 @@ CxPolicy[result] { "searchKey": sprintf("azurerm_recovery_services_vault[%s].cross_region_restore_enabled", [name]), "searchLine": common_lib.build_search_line(["resource", "azurerm_recovery_services_vault", name, "cross_region_restore_enabled"], []), "issueType": "IncorrectValue", - "keyExpectedValue": "'cross_region_restore_enabled' should be set to true", - "keyActualValue": "'cross_region_restore_enabled' is set to false", + "keyExpectedValue": "'cross_region_restore_enabled' should be set to true when 'storage_mode_type' is 'GeoRedundant'", + "keyActualValue": "'cross_region_restore_enabled' is explicitly set to false", } } From 2e90f4ee3c11a5908da0e0de72ffd71e455e9507 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:22:52 +0100 Subject: [PATCH 872/900] test: add negative case for LocallyRedundant vault --- .../test/negative2.tf | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/negative2.tf diff --git a/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/negative2.tf b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/negative2.tf new file mode 100644 index 00000000000..537260fdd1b --- /dev/null +++ b/assets/queries/terraform/azure/azure_recovery_services_vault_cross_region_restore_disabled/test/negative2.tf @@ -0,0 +1,8 @@ +# PASS: LocallyRedundant vault — cross_region_restore_enabled is not applicable +resource "azurerm_recovery_services_vault" "pass_local" { + name = "pass-vault-local" + location = "West Europe" + resource_group_name = "rg-test" + sku = "Standard" + storage_mode_type = "LocallyRedundant" +} From e86941c8568e4e24d376cf14843a9f51bfca6696 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:22:53 +0100 Subject: [PATCH 873/900] docs: enumerate checked resources; note scope limitation and library suggestion --- .../azure/azure_paas_private_endpoint_missing/metadata.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json index 38a9c981879..bb5d0594e09 100644 --- a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/metadata.json @@ -3,12 +3,12 @@ "queryName": "Beta - Ensure Private Endpoints Are Used Where Possible", "severity": "MEDIUM", "category": "Networking and Firewall", - "descriptionText": "Ensures that key Azure PaaS services (Cosmos DB, Storage, SQL, KeyVault, ACR, etc.) are accessed via Private Endpoints. While static analysis cannot resolve IDs across different state files, this rule validates local resource linkages.", - "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint", + "descriptionText": "Ensures that key Azure PaaS services are accessed via Private Endpoints, preventing exposure over the public internet. Checked resources: azurerm_cosmosdb_account, azurerm_storage_account, azurerm_mssql_server, azurerm_key_vault, azurerm_container_registry, azurerm_servicebus_namespace, azurerm_mariadb_server, azurerm_postgresql_server, azurerm_mysql_server, azurerm_redis_cache, azurerm_eventhub_namespace, azurerm_automation_account, azurerm_data_factory, azurerm_synapse_workspace, azurerm_search_service. Note: document-level check only; private endpoints defined in separate Terraform state files are not evaluated. The target resource list is defined inline; consider moving it to a platform library for easier maintenance.", + "descriptionUrl": "https://learn.microsoft.com/en-us/azure/private-link/private-endpoint-overview", "platform": "Terraform", "cloudProvider": "azure", "cwe": "200", "descriptionID": "dda11a20", "riskScore": "3.0", "experimental": "true" -} \ No newline at end of file +} From 125b86e1f3572660a76f1b278307806d3567cbeb Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:22:54 +0100 Subject: [PATCH 874/900] test: add positive case for azurerm_cosmosdb_account without private endpoint --- .../test/positive3.tf | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive3.tf diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive3.tf b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive3.tf new file mode 100644 index 00000000000..79f67220ac4 --- /dev/null +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive3.tf @@ -0,0 +1,15 @@ +resource "azurerm_cosmosdb_account" "fail_cosmos" { + name = "cosmos-fail" + location = "West Europe" + resource_group_name = "rg" + offer_type = "Standard" + kind = "GlobalDocumentDB" + + consistency_policy { + consistency_level = "Session" + } + geo_location { + location = "West Europe" + failover_priority = 0 + } +} From ec1a4beb148d45e4f09f04a57b1ab0446fbfae25 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:22:55 +0100 Subject: [PATCH 875/900] test: add positive case for azurerm_redis_cache without private endpoint --- .../azure_paas_private_endpoint_missing/test/positive4.tf | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive4.tf diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive4.tf b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive4.tf new file mode 100644 index 00000000000..3b4df216107 --- /dev/null +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive4.tf @@ -0,0 +1,8 @@ +resource "azurerm_redis_cache" "fail_redis" { + name = "redis-fail" + location = "West Europe" + resource_group_name = "rg" + capacity = 1 + family = "C" + sku_name = "Standard" +} From 0ac4df1116b83b310df4b22b15771904c41d0f86 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:22:56 +0100 Subject: [PATCH 876/900] test: add positive3.tf and positive4.tf to expected results --- .../test/positive_expected_result.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive_expected_result.json b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive_expected_result.json index d00852245b5..b5c3e42c266 100644 --- a/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/azure/azure_paas_private_endpoint_missing/test/positive_expected_result.json @@ -10,5 +10,17 @@ "severity": "MEDIUM", "line": 1, "fileName": "positive2.tf" + }, + { + "queryName": "Beta - Ensure Private Endpoints Are Used Where Possible", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive3.tf" + }, + { + "queryName": "Beta - Ensure Private Endpoints Are Used Where Possible", + "severity": "MEDIUM", + "line": 1, + "fileName": "positive4.tf" } ] From 31db70db1b7b70f7c358c5986225b4578575de82 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:22:56 +0100 Subject: [PATCH 877/900] fix: list specific flagged SKUs with documented limitations; point URL to Terraform sku_name docs --- .../metadata.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json index 081fe96f1a9..d998032989b 100644 --- a/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json +++ b/assets/queries/terraform/azure/azure_production_workload_basic_consumption_sku/metadata.json @@ -3,12 +3,12 @@ "queryName": "Beta - Production Workload using Basic or Consumption SKU", "severity": "LOW", "category": "Resource Management", - "descriptionText": "Detects the use of Basic, Free, or Consumption SKUs in Azure resources. These SKUs are often unsuitable for production workloads due to lack of SLAs, VNet integration support, or 'cold start' issues.", - "descriptionUrl": "https://azure.microsoft.com/en-us/pricing/details/app-service/linux/", + "descriptionText": "Detects Azure Service Plans and API Management instances using tiers unsuitable for production. Flagged azurerm_service_plan SKUs: B1/B2/B3 (Basic \u2014 no SLA, limited scale-out), F1/FREE (Free \u2014 no SLA, no custom domains), Y1 (Consumption \u2014 cold-start latency, no always-on). Flagged azurerm_api_management SKUs: Basic and Consumption (no VNet integration, no built-in cache, no multi-region deployment). Standard, Premium, or Isolated SKUs are recommended for production workloads.", + "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/service_plan#sku_name", "platform": "Terraform", "cloudProvider": "azure", "cwe": "1038", "descriptionID": "bd3a6fc3", "riskScore": "1.0", "experimental": "true" -} \ No newline at end of file +} From 65ab09518c4cb930e69ffbc37388a42cd9f9d477 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:28:30 +0100 Subject: [PATCH 878/900] fix(azure_bastion_host_missing): shorten descriptionText to under 500 chars --- .../terraform/azure/azure_bastion_host_missing/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json b/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json index fc194c9a38c..e90cb06a967 100644 --- a/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json +++ b/assets/queries/terraform/azure/azure_bastion_host_missing/metadata.json @@ -3,7 +3,7 @@ "queryName": "Beta - Azure Bastion Host Missing", "severity": "MEDIUM", "category": "Networking and Firewall", - "descriptionText": "Ensures that Azure Virtual Networks are protected by a Bastion Host and that the Bastion Host has a valid ip_configuration block. Azure Bastion provides secure RDP/SSH access to virtual machines without exposing them to the public internet. A complete Bastion setup requires an azurerm_bastion_host with an ip_configuration referencing a dedicated subnet named AzureBastionSubnet and a Standard-tier public IP. Note: this query verifies resource presence at the document level; subnet-level association between the Bastion and a specific VNet is not verified.", + "descriptionText": "Ensures Azure Virtual Networks are protected by a Bastion Host with a valid ip_configuration block. Azure Bastion provides secure RDP/SSH access to VMs without public internet exposure. A complete setup requires an azurerm_bastion_host with ip_configuration referencing AzureBastionSubnet and a Standard-tier public IP. Note: subnet-level VNet association is not verified.", "descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/bastion_host", "platform": "Terraform", "descriptionID": "a3e941c5", From 35c305e4c2051b6be3f6a46366c7cad7c0c2493e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:31:15 +0100 Subject: [PATCH 879/900] fix(gcp_compute_logging_service_disabled): use metadata path for searchLine in Rule 3 --- .../gcp/gcp_compute_logging_service_disabled/query.rego | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego index b3c0a719244..26f383ccd64 100644 --- a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/query.rego @@ -55,7 +55,7 @@ CxPolicy[result] { "resourceType": "google_compute_instance", "resourceName": tf_lib.get_resource_name(instance, name), "searchKey": sprintf("google_compute_instance[%s].metadata.google-logging-enabled", [name]), - "searchLine": common_lib.build_search_line(["resource", "google_compute_instance", name, "metadata", "google-logging-enabled"], []), + "searchLine": common_lib.build_search_line(["resource", "google_compute_instance", name, "metadata"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'google-logging-enabled' should be set to 'true'", "keyActualValue": "'google-logging-enabled' is set to 'false'", From 270e0c32f0e2847f4c53b7f90817d27ecb9003ef Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:31:40 +0100 Subject: [PATCH 880/900] fix(gcp_compute_logging_service_disabled): update positive3.tf expected line to 3 (metadata block) --- .../test/positive_expected_result.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive_expected_result.json b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive_expected_result.json index cca496d1ebb..63e548efd22 100644 --- a/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive_expected_result.json +++ b/assets/queries/terraform/gcp/gcp_compute_logging_service_disabled/test/positive_expected_result.json @@ -14,7 +14,7 @@ { "queryName": "Beta - GCP Compute Logging Service Disabled", "severity": "MEDIUM", - "line": 4, + "line": 3, "fileName": "positive3.tf" } ] From 544bb056f0d3599cf90585bc5c610e8dad5bb722 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:31:41 +0100 Subject: [PATCH 881/900] fix(gcp_gke_secrets_encryption_cmek_disabled): use database_encryption path for Rule 3 searchLine --- .../gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego index 4178e7d99c2..f9fea0a3595 100644 --- a/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego +++ b/assets/queries/terraform/gcp/gcp_gke_secrets_encryption_cmek_disabled/query.rego @@ -42,6 +42,7 @@ CxPolicy[result] { } # RULE 3: State is ENCRYPTED but key name (key_name) is missing. +# searchLine points to database_encryption block since key_name is absent. CxPolicy[result] { doc := input.document[i] cluster := doc.resource.google_container_cluster[name] @@ -56,7 +57,7 @@ CxPolicy[result] { "resourceType": "google_container_cluster", "resourceName": tf_lib.get_resource_name(cluster, name), "searchKey": sprintf("google_container_cluster[%s].database_encryption.key_name", [name]), - "searchLine": common_lib.build_search_line(["resource", "google_container_cluster", name, "database_encryption", "key_name"], []), + "searchLine": common_lib.build_search_line(["resource", "google_container_cluster", name, "database_encryption"], []), "issueType": "MissingAttribute", "keyExpectedValue": "'key_name' should be defined with a valid KMS key ID", "keyActualValue": "'key_name' is missing or empty", From 7a48bd9bb0eb8710bd3f079945d654729dc2447e Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:44:41 +0100 Subject: [PATCH 882/900] fix: add missing common_lib import and searchLine --- .../query.rego | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego index 43755080a35..559a1197297 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_global_events_disabled/query.rego @@ -1,6 +1,8 @@ package Cx -# RULE 1: Does not exist ningún resource 'ibm_resource_instance' para 'activity-tracker'. +import data.generic.common as common_lib + +# RULE 1: No ibm_resource_instance for activity-tracker exists in the configuration. CxPolicy[result] { doc := input.document[i] _ := doc.provider.ibm @@ -22,7 +24,7 @@ CxPolicy[result] { } } -# RULE 2: Una instancia de 'activity-tracker' está en una región incorrecta para events globales. +# RULE 2: An activity-tracker instance is in a region that does not support global events. CxPolicy[result] { global_event_regions := {"eu-de", "eu-gb", "us-south", "au-syd"} @@ -34,8 +36,9 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.ibm_resource_instance.%s.location", [tracker_name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_resource_instance", tracker_name, "location"], []), "issueType": "IncorrectValue", "keyExpectedValue": "Activity Tracker 'location' should be a global event region (e.g., 'eu-de', 'us-south')", "keyActualValue": sprintf("Activity Tracker 'location' is '%s', which is not a global event region", [tracker.location]), } -} \ No newline at end of file +} From 5dd0d9b32f0cd23519d5be41e58d89c04746c3d1 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:44:42 +0100 Subject: [PATCH 883/900] fix: add missing common_lib import and searchLine --- .../query.rego | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego index fb8dfc6e424..c3604949d36 100644 --- a/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_activity_tracker_platform_logs_disabled/query.rego @@ -1,6 +1,8 @@ package Cx -# RULE 1: Does not exist ningún resource 'ibm_resource_instance' para el servicio 'activity-tracker'. +import data.generic.common as common_lib + +# RULE 1: No ibm_resource_instance for activity-tracker exists in the configuration. CxPolicy[result] { doc := input.document[i] _ := doc.provider.ibm @@ -22,7 +24,7 @@ CxPolicy[result] { } } -# RULE 2: The 'platform_logs' attribute is missing en la instancia de Activity Tracker. +# RULE 2: The 'platform_logs' attribute is missing from the Activity Tracker instance. CxPolicy[result] { tracker := input.document[i].resource.ibm_resource_instance[tracker_name] tracker.service == "activity-tracker" @@ -32,13 +34,14 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.ibm_resource_instance.%s", [tracker_name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_resource_instance", tracker_name], []), "issueType": "MissingAttribute", "keyExpectedValue": "'platform_logs' attribute should be present and set to 'true'", "keyActualValue": "'platform_logs' attribute is missing and defaults to 'false'", } } -# RULE 3: The attribute 'platform_logs' está explícitamente configurado como 'false'. +# RULE 3: The 'platform_logs' attribute is explicitly set to 'false'. CxPolicy[result] { tracker := input.document[i].resource.ibm_resource_instance[tracker_name] tracker.service == "activity-tracker" @@ -48,8 +51,9 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.ibm_resource_instance.%s.platform_logs", [tracker_name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_resource_instance", tracker_name, "platform_logs"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'platform_logs' attribute should be 'true'", "keyActualValue": "'platform_logs' attribute is 'false'", } -} \ No newline at end of file +} From 232d9f51487e1d31920fdc67e23e6d950f454683 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:44:43 +0100 Subject: [PATCH 884/900] fix: add missing common_lib import and searchLine --- .../ibm/ibm_iam_account_mfa_disabled/query.rego | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego index 04e5d11064f..45d3fea1cae 100644 --- a/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego +++ b/assets/queries/terraform/ibm/ibm_iam_account_mfa_disabled/query.rego @@ -1,6 +1,8 @@ package Cx -# RULE 1: El resource 'ibm_iam_account_settings' Does not exist en la configuración. +import data.generic.common as common_lib + +# RULE 1: No ibm_iam_account_settings resource exists in the configuration. CxPolicy[result] { doc := input.document[i] _ := doc.provider.ibm @@ -21,7 +23,7 @@ CxPolicy[result] { } } -# RULE 2: The 'mfa' attribute is missing within the resource. +# RULE 2: The 'mfa' attribute is missing from the resource. CxPolicy[result] { settings := input.document[i].resource.ibm_iam_account_settings[settings_name] object.get(settings, "mfa", null) == null @@ -29,13 +31,14 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.ibm_iam_account_settings.%s", [settings_name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_iam_account_settings", settings_name], []), "issueType": "MissingAttribute", "keyExpectedValue": "'mfa' attribute should be present and set to 'LEVEL2' or 'LEVEL3'", "keyActualValue": "'mfa' attribute is missing", } } -# RULE 3: The attribute 'mfa' tiene un valor inseguro ('NONE' o 'LEVEL1'). +# RULE 3: The 'mfa' attribute is set to an insecure value ('NONE' or 'LEVEL1'). CxPolicy[result] { settings := input.document[i].resource.ibm_iam_account_settings[settings_name] insecure_mfa_levels := {"NONE", "LEVEL1"} @@ -44,8 +47,9 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.ibm_iam_account_settings.%s.mfa", [settings_name]), + "searchLine": common_lib.build_search_line(["resource", "ibm_iam_account_settings", settings_name, "mfa"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'mfa' attribute should be 'LEVEL2' or 'LEVEL3'", "keyActualValue": sprintf("'mfa' attribute is set to '%s'", [settings.mfa]), } -} \ No newline at end of file +} From c6afbf85d4564695a844f1cf50d215567d7df148 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:44:43 +0100 Subject: [PATCH 885/900] fix: add missing common_lib import --- .../query.rego | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/query.rego index 7278f61dfca..b3d1a779102 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_cloud_guard_problem_event_rule_missing/query.rego @@ -1,25 +1,27 @@ -package Cx - -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - expected_event_type := "com.oraclecloud.cloudguard.problem" - - rules_with_correct_event := [rule | - rule := input.document[_].resource.oci_events_rule[_] - rule.is_enabled == true - contains(rule.condition, expected_event_type) - ] - - count(rules_with_correct_event) == 0 - - result := { - "documentId": doc.id, +package Cx + +import data.generic.common as common_lib + +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + expected_event_type := "com.oraclecloud.cloudguard.problem" + + rules_with_correct_event := [rule | + rule := input.document[_].resource.oci_events_rule[_] + rule.is_enabled == true + contains(rule.condition, expected_event_type) + ] + + count(rules_with_correct_event) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "An 'oci_events_rule' for Cloud Guard problems should exist in the project", - "keyActualValue": "No 'oci_events_rule' is configured to audit Cloud Guard problems", - } -} \ No newline at end of file + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "An 'oci_events_rule' for Cloud Guard problems should exist in the project", + "keyActualValue": "No 'oci_events_rule' is configured to audit Cloud Guard problems", + } +} From 951d3ec3237c2531adc9dd107e5d8720f734061b Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:44:44 +0100 Subject: [PATCH 886/900] fix: add missing common_lib import and searchLine --- .../query.rego | 92 ++++++++++--------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego index 9e2b8325c48..50cacab5242 100644 --- a/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego +++ b/assets/queries/terraform/oci/oci_cloud_guard_root_compartment_disabled/query.rego @@ -1,53 +1,57 @@ package Cx -# RULE 1: Does not exist ningún resource 'oci_cloud_guard_configuration'. +import data.generic.common as common_lib + +# RULE 1: No oci_cloud_guard_configuration resource exists. CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - all_cloud_guards := [cg | - cg := input.document[_].resource.oci_cloud_guard_configuration[_] - ] - - count(all_cloud_guards) == 0 - - result := { - "documentId": doc.id, - "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "Resource 'oci_cloud_guard_configuration' should exist to enable Cloud Guard", - "keyActualValue": "Resource 'oci_cloud_guard_configuration' is missing", - } + doc := input.document[i] + _ := doc.provider.oci + + all_cloud_guards := [cg | + cg := input.document[_].resource.oci_cloud_guard_configuration[_] + ] + + count(all_cloud_guards) == 0 + + result := { + "documentId": doc.id, + "searchKey": "provider.oci", + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "Resource 'oci_cloud_guard_configuration' should exist to enable Cloud Guard", + "keyActualValue": "Resource 'oci_cloud_guard_configuration' is missing", + } } -# RULE 2: Cloud Guard Exists, but su 'status' no es 'ENABLED'. +# RULE 2: Cloud Guard exists but its 'status' is not 'ENABLED'. CxPolicy[result] { - cg := input.document[i].resource.oci_cloud_guard_configuration[cg_name] - - cg.status != "ENABLED" - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_cloud_guard_configuration.%s.status", [cg_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'status' attribute should be 'ENABLED'", - "keyActualValue": sprintf("'status' attribute is '%s'", [cg.status]), - } + cg := input.document[i].resource.oci_cloud_guard_configuration[cg_name] + + cg.status != "ENABLED" + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_cloud_guard_configuration.%s.status", [cg_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_cloud_guard_configuration", cg_name, "status"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'status' attribute should be 'ENABLED'", + "keyActualValue": sprintf("'status' attribute is '%s'", [cg.status]), + } } -# RULE 3: Cloud Guard Exists y is enabled, but no en el compartimento raíz. +# RULE 3: Cloud Guard is enabled but not at the root compartment. CxPolicy[result] { - cg := input.document[i].resource.oci_cloud_guard_configuration[cg_name] - - cg.status == "ENABLED" - not contains(lower(cg.compartment_id), "tenancy") - - result := { - "documentId": input.document[i].id, - "searchKey": sprintf("resource.oci_cloud_guard_configuration.%s.compartment_id", [cg_name]), - "issueType": "IncorrectValue", - "keyExpectedValue": "'compartment_id' should be the tenancy (root compartment) OCID", - "keyActualValue": "'compartment_id' is not the tenancy OCID", - } -} \ No newline at end of file + cg := input.document[i].resource.oci_cloud_guard_configuration[cg_name] + + cg.status == "ENABLED" + not contains(lower(cg.compartment_id), "tenancy") + + result := { + "documentId": input.document[i].id, + "searchKey": sprintf("resource.oci_cloud_guard_configuration.%s.compartment_id", [cg_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_cloud_guard_configuration", cg_name, "compartment_id"], []), + "issueType": "IncorrectValue", + "keyExpectedValue": "'compartment_id' should be the tenancy (root compartment) OCID", + "keyActualValue": "'compartment_id' is not the tenancy OCID", + } +} From 173c7ebeb630f42f811ebc530359d0f8976a5c01 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:44:45 +0100 Subject: [PATCH 887/900] fix: add missing common_lib import --- .../oci_default_tags_not_defined/query.rego | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/assets/queries/terraform/oci/oci_default_tags_not_defined/query.rego b/assets/queries/terraform/oci/oci_default_tags_not_defined/query.rego index d816de85896..355fcd1c6de 100644 --- a/assets/queries/terraform/oci/oci_default_tags_not_defined/query.rego +++ b/assets/queries/terraform/oci/oci_default_tags_not_defined/query.rego @@ -1,21 +1,23 @@ -package Cx - -CxPolicy[result] { - doc := input.document[i] - _ := doc.provider.oci - - all_default_tags := [tag | - tag := input.document[_].resource.oci_identity_tag_default[_] - ] - - count(all_default_tags) == 0 - - result := { - "documentId": doc.id, +package Cx + +import data.generic.common as common_lib + +CxPolicy[result] { + doc := input.document[i] + _ := doc.provider.oci + + all_default_tags := [tag | + tag := input.document[_].resource.oci_identity_tag_default[_] + ] + + count(all_default_tags) == 0 + + result := { + "documentId": doc.id, "searchKey": "provider.oci", - "searchLine": common_lib.build_search_line(["provider", "oci"], []), - "issueType": "MissingAttribute", - "keyExpectedValue": "At least one 'oci_identity_tag_default' resource should exist to define a default tagging policy", - "keyActualValue": "No 'oci_identity_tag_default' resource was found in the configuration", - } -} \ No newline at end of file + "searchLine": common_lib.build_search_line(["provider", "oci"], []), + "issueType": "MissingAttribute", + "keyExpectedValue": "At least one 'oci_identity_tag_default' resource should exist to define a default tagging policy", + "keyActualValue": "No 'oci_identity_tag_default' resource was found in the configuration", + } +} From 9dc3ac3d94647b853571942b471102dde00ad272 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:44:46 +0100 Subject: [PATCH 888/900] fix: add missing common_lib import and searchLine --- .../query.rego | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego index d58c6f05d9f..1a95d134691 100644 --- a/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_iam_group_change_event_rule_missing/query.rego @@ -1,20 +1,20 @@ package Cx +import data.generic.common as common_lib + expected_event_types := [ "com.oraclecloud.identity.creategroup", "com.oraclecloud.identity.updategroup", "com.oraclecloud.identity.deletegroup" ] -# RULE 1: Missing (Global) -# No rule exists in the project monitoring events de IAM (ni siquiera parcialmente). +# RULE 1: No rule exists in the project monitoring IAM group change events. CxPolicy[result] { doc := input.document[i] _ := doc.provider.oci any_iam_rule := [rule | rule := input.document[_].resource.oci_events_rule[_] - event := expected_event_types[_] contains(rule.condition, event) ] @@ -31,16 +31,15 @@ CxPolicy[result] { } } -# RULE 2: Incomplete (Local) -# The rule Exists y mira events de IAM, but le Missing alguno de los 3 requeridos. +# RULE 2: A rule exists but is missing some of the 3 required events. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] - + count(matches) > 0 count(matches) < count(expected_event_types) @@ -49,18 +48,18 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "condition"], []), "issueType": "IncorrectValue", "keyExpectedValue": "The rule condition should include all 3 IAM group events (create, update, delete)", "keyActualValue": sprintf("The rule is missing %d IAM group event(s)", [missing_count]), } } -# RULE 3: Disabled (Local) -# The rule has all the correct events but is disabled. +# RULE 3: A rule has all events but is disabled. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] @@ -71,8 +70,9 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "is_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'is_enabled' should be true", "keyActualValue": "'is_enabled' is false", } -} \ No newline at end of file +} From 4056f601840f5786e023227be4de7cbd3dc5a82f Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:44:47 +0100 Subject: [PATCH 889/900] fix: add missing common_lib import and searchLine --- .../query.rego | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego index bb0523dfec3..3d019703f0e 100644 --- a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/query.rego @@ -1,13 +1,14 @@ package Cx +import data.generic.common as common_lib + expected_event_types := [ "com.oraclecloud.identity.createpolicy", "com.oraclecloud.identity.updatepolicy", "com.oraclecloud.identity.deletepolicy" ] -# RULE 1: Missing (Global) -# No rule exists in the project monitoring events de Políticas IAM. +# RULE 1: No rule exists in the project monitoring IAM Policy change events. CxPolicy[result] { doc := input.document[i] _ := doc.provider.oci @@ -30,16 +31,15 @@ CxPolicy[result] { } } -# RULE 2: Incomplete (Local) -# The rule Exists y mira events de Políticas, but le Missing alguno de los 3 requeridos. +# RULE 2: A rule exists but is missing some of the 3 required events. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] - + count(matches) > 0 count(matches) < count(expected_event_types) @@ -48,18 +48,18 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "condition"], []), "issueType": "IncorrectValue", "keyExpectedValue": "The rule condition should include all 3 IAM Policy events (create, update, delete)", "keyActualValue": sprintf("The rule is missing %d IAM Policy event(s)", [missing_count]), } } -# RULE 3: Disabled (Local) -# The rule has all the correct events but is disabled. +# RULE 3: A rule has all events but is disabled. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] @@ -70,8 +70,9 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "is_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'is_enabled' should be true", "keyActualValue": "'is_enabled' is false", } -} \ No newline at end of file +} From db3de0e6f7a140860f91c3414589f40ef22765db Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:44:47 +0100 Subject: [PATCH 890/900] fix: add missing common_lib import and searchLine --- .../query.rego | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego index 2207ee786e3..765b09fe0c7 100644 --- a/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_iam_user_change_event_rule_missing/query.rego @@ -1,5 +1,7 @@ package Cx +import data.generic.common as common_lib + expected_event_types := [ "com.oraclecloud.identity.createuser", "com.oraclecloud.identity.updateuser", @@ -8,8 +10,7 @@ expected_event_types := [ "com.oraclecloud.identity.disableuser" ] -# RULE 1: Missing (Global) -# No rule exists in the project monitoring events de usuarios. +# RULE 1: No rule exists in the project monitoring IAM User change events. CxPolicy[result] { doc := input.document[i] _ := doc.provider.oci @@ -32,16 +33,15 @@ CxPolicy[result] { } } -# RULE 2: Incomplete (Local) -# The rule Exists y es relevante, but le Missing alguno de los 5 events. +# RULE 2: A rule exists but is missing some of the 5 required events. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] - + count(matches) > 0 count(matches) < count(expected_event_types) @@ -50,18 +50,18 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "condition"], []), "issueType": "IncorrectValue", "keyExpectedValue": "The rule condition should include all 5 IAM User events", "keyActualValue": sprintf("The rule is missing %d IAM User event(s)", [missing_count]), } } -# RULE 3: Disabled (Local) -# Si es una regla de Usuarios (relevante) y está apagada -> FALLO CRÍTICO. +# RULE 3: A relevant rule exists but is disabled. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] @@ -72,8 +72,9 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "is_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'is_enabled' should be true", "keyActualValue": "'is_enabled' is false", } -} \ No newline at end of file +} From c950d774df35d7f5bce0a20c0ad23ef43997f74d Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:44:48 +0100 Subject: [PATCH 891/900] fix: add missing common_lib import and searchLine --- .../oci/oci_idp_change_event_rule_missing/query.rego | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego index 27bbef7790a..05f0067b85e 100644 --- a/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_idp_change_event_rule_missing/query.rego @@ -1,9 +1,10 @@ package Cx +import data.generic.common as common_lib + expected_event := "com.oraclecloud.identitycontrolplane.updateidentityprovider" -# RULE 1: Missing (Global) -# No rule exists in the project monitoring el evento de Identity Provider. +# RULE 1: No rule exists in the project monitoring Identity Provider changes. CxPolicy[result] { doc := input.document[i] _ := doc.provider.oci @@ -25,8 +26,7 @@ CxPolicy[result] { } } -# RULE 2: Disabled (Local) -# The rule Exists y monitorea IdP, but is disabled. +# RULE 2: A rule monitors IdP events but is disabled. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] @@ -37,8 +37,9 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "is_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'is_enabled' should be true", "keyActualValue": "'is_enabled' is false", } -} \ No newline at end of file +} From f04c90de57d75f0214c191712667f9e90dc12c66 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:45:05 +0100 Subject: [PATCH 892/900] fix(oci_iam_policy_change_event_rule_missing): correct positive1.tf expected line to 1 --- .../test/positive_expected_result.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive_expected_result.json b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive_expected_result.json index c66835f31e2..9bdb1dcec81 100644 --- a/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive_expected_result.json +++ b/assets/queries/terraform/oci/oci_iam_policy_change_event_rule_missing/test/positive_expected_result.json @@ -2,7 +2,7 @@ { "queryName": "Beta - Event Rule for IAM Policy Changes is Missing", "severity": "HIGH", - "line": 2, + "line": 1, "fileName": "positive1.tf" }, { From f6601e146c47a52330e4162089cfdb59488ca2a8 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:54:05 +0100 Subject: [PATCH 893/900] fix: add missing common_lib import and searchLine --- .../query.rego | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego index 3520c4638fb..55135d0d0c7 100644 --- a/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_vcn_change_event_rule_missing/query.rego @@ -1,24 +1,25 @@ package Cx +import data.generic.common as common_lib + expected_event_types := [ "com.oraclecloud.virtualnetwork.createvcn", "com.oraclecloud.virtualnetwork.updatevcn", "com.oraclecloud.virtualnetwork.deletevcn" ] -# RULE 1: Missing (Global) -# No rule exists in the project monitoring cambios en VCNs. +# RULE 1: No rule exists in the project monitoring VCN change events. CxPolicy[result] { doc := input.document[i] _ := doc.provider.oci - any_vcn_rule := [rule | + any_rule := [rule | rule := input.document[_].resource.oci_events_rule[_] event := expected_event_types[_] contains(rule.condition, event) ] - count(any_vcn_rule) == 0 + count(any_rule) == 0 result := { "documentId": doc.id, @@ -30,16 +31,15 @@ CxPolicy[result] { } } -# RULE 2: Incomplete (Local) -# The rule exists but is missing events (ej: tiene create but Missing delete). +# RULE 2: A rule exists but is missing some of the required events. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] - + count(matches) > 0 count(matches) < count(expected_event_types) @@ -48,29 +48,31 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "condition"], []), "issueType": "IncorrectValue", - "keyExpectedValue": "The rule condition should include all 3 VCN events (create, update, delete)", + "keyExpectedValue": "The rule condition should include all required VCN events", "keyActualValue": sprintf("The rule is missing %d VCN event(s)", [missing_count]), } } -# RULE 3: Disabled (Local) -# The rule es relevante para VCN but está apagada. +# RULE 3: A relevant rule exists but is disabled. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] count(matches) > 0 + rule.is_enabled == false result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "is_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'is_enabled' should be true", "keyActualValue": "'is_enabled' is false", } -} \ No newline at end of file +} From ffc2a4b104e15afdc1197a56776ccbcae59b05de Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:54:05 +0100 Subject: [PATCH 894/900] fix: add missing common_lib import and searchLine --- .../query.rego | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego index eb7027efa2c..261cb40ab8c 100644 --- a/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_security_list_change_event_rule_missing/query.rego @@ -1,24 +1,25 @@ package Cx +import data.generic.common as common_lib + expected_event_types := [ "com.oraclecloud.virtualnetwork.createsecuritylist", "com.oraclecloud.virtualnetwork.updatesecuritylist", "com.oraclecloud.virtualnetwork.deletesecuritylist" ] -# RULE 1: Missing (Global) -# No rule exists in the project monitoring Security Lists. +# RULE 1: No rule exists in the project monitoring Security List change events. CxPolicy[result] { doc := input.document[i] _ := doc.provider.oci - any_sl_rule := [rule | + any_rule := [rule | rule := input.document[_].resource.oci_events_rule[_] event := expected_event_types[_] contains(rule.condition, event) ] - count(any_sl_rule) == 0 + count(any_rule) == 0 result := { "documentId": doc.id, @@ -30,16 +31,15 @@ CxPolicy[result] { } } -# RULE 2: Incomplete (Local) -# The rule exists but is missing events (ej: tiene create but Missing delete). +# RULE 2: A rule exists but is missing some of the required events. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] - + count(matches) > 0 count(matches) < count(expected_event_types) @@ -48,29 +48,31 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "condition"], []), "issueType": "IncorrectValue", - "keyExpectedValue": "The rule condition should include all 3 Security List events (create, update, delete)", + "keyExpectedValue": "The rule condition should include all required Security List events", "keyActualValue": sprintf("The rule is missing %d Security List event(s)", [missing_count]), } } -# RULE 3: Disabled (Local) -# The rule es relevante para Security Lists but está apagada. +# RULE 3: A relevant rule exists but is disabled. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] count(matches) > 0 + rule.is_enabled == false result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "is_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'is_enabled' should be true", "keyActualValue": "'is_enabled' is false", } -} \ No newline at end of file +} From f2468c7932a015565c9a515d0466ba7cb4ab86cd Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:54:06 +0100 Subject: [PATCH 895/900] fix: add missing common_lib import and searchLine --- .../query.rego | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego index 7315c3e9b83..6b1ea134ea8 100644 --- a/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_route_table_change_event_rule_missing/query.rego @@ -1,24 +1,25 @@ package Cx +import data.generic.common as common_lib + expected_event_types := [ "com.oraclecloud.virtualnetwork.createroutetable", "com.oraclecloud.virtualnetwork.updateroutetable", "com.oraclecloud.virtualnetwork.deleteroutetable" ] -# RULE 1: Missing (Global) -# No rule exists in the project monitoring Route Tables. +# RULE 1: No rule exists in the project monitoring Route Table change events. CxPolicy[result] { doc := input.document[i] _ := doc.provider.oci - any_rt_rule := [rule | + any_rule := [rule | rule := input.document[_].resource.oci_events_rule[_] event := expected_event_types[_] contains(rule.condition, event) ] - count(any_rt_rule) == 0 + count(any_rule) == 0 result := { "documentId": doc.id, @@ -30,16 +31,15 @@ CxPolicy[result] { } } -# RULE 2: Incomplete (Local) -# The rule Exists, but is missing events (ej: tiene create but Missing update). +# RULE 2: A rule exists but is missing some of the required events. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] - + count(matches) > 0 count(matches) < count(expected_event_types) @@ -48,18 +48,18 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "condition"], []), "issueType": "IncorrectValue", - "keyExpectedValue": "The rule condition should include all 3 Route Table events (create, update, delete)", + "keyExpectedValue": "The rule condition should include all required Route Table events", "keyActualValue": sprintf("The rule is missing %d Route Table event(s)", [missing_count]), } } -# RULE 3: Disabled (Local) -# The rule es relevante (Route Table) but está apagada. +# RULE 3: A relevant rule exists but is disabled. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] @@ -70,8 +70,9 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "is_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'is_enabled' should be true", "keyActualValue": "'is_enabled' is false", } -} \ No newline at end of file +} From 9a06fa91aabf6678b31d4b256eba9f3a5db0beb7 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:54:07 +0100 Subject: [PATCH 896/900] fix: add missing common_lib import and searchLine --- .../query.rego | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego index 37c84f0b62e..da62046d3b6 100644 --- a/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_nsg_change_event_rule_missing/query.rego @@ -1,24 +1,25 @@ package Cx +import data.generic.common as common_lib + expected_event_types := [ "com.oraclecloud.virtualnetwork.createnetworksecuritygroup", "com.oraclecloud.virtualnetwork.updatenetworksecuritygroup", "com.oraclecloud.virtualnetwork.deletenetworksecuritygroup" ] -# RULE 1: Missing (Global) -# No rule exists in the project monitoring NSGs. +# RULE 1: No rule exists in the project monitoring Network Security Group change events. CxPolicy[result] { doc := input.document[i] _ := doc.provider.oci - any_nsg_rule := [rule | + any_rule := [rule | rule := input.document[_].resource.oci_events_rule[_] event := expected_event_types[_] contains(rule.condition, event) ] - count(any_nsg_rule) == 0 + count(any_rule) == 0 result := { "documentId": doc.id, @@ -30,16 +31,15 @@ CxPolicy[result] { } } -# RULE 2: Incomplete (Local) -# The rule Exists, but is missing events (ej: tiene create but Missing delete). +# RULE 2: A rule exists but is missing some of the required events. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] - + count(matches) > 0 count(matches) < count(expected_event_types) @@ -48,18 +48,18 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "condition"], []), "issueType": "IncorrectValue", - "keyExpectedValue": "The rule condition should include all 3 NSG events (create, update, delete)", - "keyActualValue": sprintf("The rule is missing %d NSG event(s)", [missing_count]), + "keyExpectedValue": "The rule condition should include all required Network Security Group events", + "keyActualValue": sprintf("The rule is missing %d Network Security Group event(s)", [missing_count]), } } -# RULE 3: Disabled (Local) -# The rule es relevante (NSG) but está apagada. +# RULE 3: A relevant rule exists but is disabled. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] @@ -70,8 +70,9 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "is_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'is_enabled' should be true", "keyActualValue": "'is_enabled' is false", } -} \ No newline at end of file +} From f063fafaac1f5dbd76840334c093bb4189af7da9 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:54:08 +0100 Subject: [PATCH 897/900] fix: add missing common_lib import and searchLine --- .../query.rego | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego index c5bbf7b32b5..cb4314ceed0 100644 --- a/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_network_gateway_change_event_rule_missing/query.rego @@ -1,5 +1,7 @@ package Cx +import data.generic.common as common_lib + expected_event_types := [ "com.oraclecloud.virtualnetwork.createinternetgateway", "com.oraclecloud.virtualnetwork.updateinternetgateway", @@ -18,19 +20,18 @@ expected_event_types := [ "com.oraclecloud.virtualnetwork.deletelocalpeeringgateway" ] -# RULE 1: Missing (Global) -# No rule exists in the project monitoring Gateways. +# RULE 1: No rule exists in the project monitoring Network Gateway change events. CxPolicy[result] { doc := input.document[i] _ := doc.provider.oci - any_gateway_rule := [rule | + any_rule := [rule | rule := input.document[_].resource.oci_events_rule[_] event := expected_event_types[_] contains(rule.condition, event) ] - count(any_gateway_rule) == 0 + count(any_rule) == 0 result := { "documentId": doc.id, @@ -42,16 +43,15 @@ CxPolicy[result] { } } -# RULE 2: Incomplete (Local) -# The rule Exists, but is missing events (ej. tiene IGW but Missing NAT). +# RULE 2: A rule exists but is missing some of the required events. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] - + count(matches) > 0 count(matches) < count(expected_event_types) @@ -60,18 +60,18 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.condition", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "condition"], []), "issueType": "IncorrectValue", - "keyExpectedValue": "The rule condition should include all 15 Network Gateway events", + "keyExpectedValue": "The rule condition should include all required Network Gateway events", "keyActualValue": sprintf("The rule is missing %d Network Gateway event(s)", [missing_count]), } } -# RULE 3: Disabled (Local) -# The rule es relevante (gateways) but está apagada. +# RULE 3: A relevant rule exists but is disabled. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] - matches := [event | + matches := [event | event := expected_event_types[_] contains(rule.condition, event) ] @@ -82,8 +82,9 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "is_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'is_enabled' should be true", "keyActualValue": "'is_enabled' is false", } -} \ No newline at end of file +} From 3369e0e5d96b09f301083e5606987bbfd00acfd3 Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:54:08 +0100 Subject: [PATCH 898/900] fix: add missing common_lib import and searchLine --- .../query.rego | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego index d6bc9c3e827..9e8568d9ae0 100644 --- a/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego +++ b/assets/queries/terraform/oci/oci_notification_topic_without_subscription/query.rego @@ -1,7 +1,8 @@ package Cx -# RULE 1: Missing (Global) -# Does not exist ningún resource 'oci_ons_notification_topic' en todo el documento. +import data.generic.common as common_lib + +# RULE 1: No oci_ons_notification_topic resource exists in the configuration. CxPolicy[result] { doc := input.document[i] _ := doc.provider.oci @@ -22,8 +23,7 @@ CxPolicy[result] { } } -# RULE 2: Orphan Topic (Local) -# Exists un tópico, but NO suscripción apunta a él. +# RULE 2: A notification topic exists but has no subscription pointing to it. CxPolicy[result] { doc := input.document[i] _ := doc.resource.oci_ons_notification_topic[topic_name] @@ -38,8 +38,9 @@ CxPolicy[result] { result := { "documentId": doc.id, "searchKey": sprintf("resource.oci_ons_notification_topic.%s", [topic_name]), + "searchLine": common_lib.build_search_line(["resource", "oci_ons_notification_topic", topic_name], []), "issueType": "MissingAttribute", "keyExpectedValue": "'oci_ons_notification_topic' should have at least one associated 'oci_ons_subscription'", "keyActualValue": "'oci_ons_notification_topic' has no subscriptions", } -} \ No newline at end of file +} From 64878393dd4af44ec887051c22b648bea0f1c7cd Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:54:09 +0100 Subject: [PATCH 899/900] fix: add missing common_lib import and searchLine --- .../query.rego | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego index b08119f3ad8..de4ce0814ae 100644 --- a/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_local_user_authentication_event_rule_missing/query.rego @@ -1,19 +1,20 @@ package Cx +import data.generic.common as common_lib + expected_event := "com.oraclecloud.identity.localuser.authenticate" -# RULE 1: Missing (Global) -# No rule exists in the project monitoring el evento de autenticación local. +# RULE 1: No rule exists in the project monitoring local user authentication events. CxPolicy[result] { doc := input.document[i] _ := doc.provider.oci - any_auth_rule := [rule | + any_rule := [rule | rule := input.document[_].resource.oci_events_rule[_] contains(rule.condition, expected_event) ] - count(any_auth_rule) == 0 + count(any_rule) == 0 result := { "documentId": doc.id, @@ -25,8 +26,7 @@ CxPolicy[result] { } } -# RULE 2: Disabled (Local) -# The rule Exists y monitorea autenticación, but is disabled. +# RULE 2: A relevant rule exists but is disabled. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] @@ -37,8 +37,9 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "is_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'is_enabled' should be true", "keyActualValue": "'is_enabled' is false", } -} \ No newline at end of file +} From 7da3fd8fa49d69481e61b7678a4e40cc348691be Mon Sep 17 00:00:00 2001 From: Antero Silva Date: Wed, 15 Apr 2026 23:54:10 +0100 Subject: [PATCH 900/900] fix: add missing common_lib import and searchLine --- .../query.rego | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego index c8dc1f9b5a0..95ca8cf10d1 100644 --- a/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego +++ b/assets/queries/terraform/oci/oci_idp_group_mapping_change_event_rule_missing/query.rego @@ -1,32 +1,32 @@ package Cx +import data.generic.common as common_lib + expected_event := "com.oraclecloud.identitycontrolplane.updateidpgroupmapping" -# RULE 1: Missing (Global) -# No rule exists in the project monitoring el evento de IdP Group Mapping. +# RULE 1: No rule exists in the project monitoring IdP group mapping changes events. CxPolicy[result] { doc := input.document[i] _ := doc.provider.oci - any_mapping_rule := [rule | + any_rule := [rule | rule := input.document[_].resource.oci_events_rule[_] contains(rule.condition, expected_event) ] - count(any_mapping_rule) == 0 + count(any_rule) == 0 result := { "documentId": doc.id, "searchKey": "provider.oci", "searchLine": common_lib.build_search_line(["provider", "oci"], []), "issueType": "MissingAttribute", - "keyExpectedValue": "An 'oci_events_rule' for IdP group mapping changes should exist", + "keyExpectedValue": "An 'oci_events_rule' for IdP group mapping changes events should exist", "keyActualValue": "No 'oci_events_rule' found for IdP group mapping changes", } } -# RULE 2: Disabled (Local) -# The rule Exists y monitorea el mapeo, but is disabled. +# RULE 2: A relevant rule exists but is disabled. CxPolicy[result] { rule := input.document[i].resource.oci_events_rule[name] @@ -37,8 +37,9 @@ CxPolicy[result] { result := { "documentId": input.document[i].id, "searchKey": sprintf("resource.oci_events_rule.%s.is_enabled", [name]), + "searchLine": common_lib.build_search_line(["resource", "oci_events_rule", name, "is_enabled"], []), "issueType": "IncorrectValue", "keyExpectedValue": "'is_enabled' should be true", "keyActualValue": "'is_enabled' is false", } -} \ No newline at end of file +}