Beta - Logs And Alerts Missing Project Ownership Assignment And Changes

  • Query id: a881b71c-73ac-4358-879c-e3271db5a3c5
  • Query name: Beta - Logs And Alerts Missing Project Ownership Assignment And Changes
  • Platform: Terraform
  • Severity: Medium
  • Category: Observability
  • CWE: 778
  • Risk score: 3.0
  • URL: Github

Description

Resources google_monitoring_alert_policy and google_logging_metric filter fields should capture a logging metric whose filter defines protoPayload.serviceName=cloudresourcemanager.googleapis.com AND (ProjectOwnership OR projectOwnerInvitee) OR (bindingDeltas.action=REMOVE AND bindingDeltas.role=roles/owner) OR (bindingDeltas.action=ADD AND bindingDeltas.role=roles/owner). All AND/OR operators must be explicit and notification_channels defined on google_monitoring_alert_policy.
Documentation

Code samples

Code samples with security vulnerabilities

Positive test num. 1 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
    (protoPayload.serviceName="Wrong_service_name")
    AND (ProjectOwnership OR projectOwnerInvitee)
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
  # incorrect filter
}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"
    condition_threshold {
      filter = "resource.type=\"gce_instance\" AND metric.type=\"logging.googleapis.com/user/audit_config_change\""
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
}
Positive test num. 2 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
  (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
  AND (ProjectOwnership OR projectOwnerInvitee)
  OR NOT(NOT protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
      AND NOT protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
      AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  OR (protoPayload.methodName="SetIamPolicy")
FILTER
}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"
    condition_threshold {
      filter = "resource.type=\"gce_instance\" AND metric.type=\"logging.googleapis.com/user/audit_config_change\""
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
}
Positive test num. 3 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
    (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
    AND (ProjectOwnership OR projectOwnerInvitee)
    OR NOT (NOT protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    AND NOT protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert (Log Match)"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"        # test for unusual spacing
    condition_matched_log {
      filter = <<-FILTER
         ( protoPayload.serviceName  = "cloudresourcemanager.googleapis.com" )
        AND
         ( ProjectOwnership   OR projectOwnerInvitee  )
        OR  NOT ( NOT protoPayload.serviceData.policyDelta.bindingDeltas.action   =  "REMOVE"
        AND NOT protoPayload.serviceData.policyDelta.bindingDeltas.role  =   "roles/owner" )
        OR
         (
          protoPayload.serviceData.policyDelta.bindingDeltas.action =   "ADD" AND
            protoPayload.serviceData.policyDelta.bindingDeltas.role   = "roles/owner"
            )
      FILTER
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
}

Positive test num. 4 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
  (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
  AND NOT (NOT ProjectOwnership OR NOT projectOwnerInvitee)
  OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
      AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
      AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  OR (protoPayload.methodName="SetIamPolicy")
FILTER

}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"
    condition_threshold {
      filter = "resource.type=\"gce_instance\" AND metric.type=\"logging.googleapis.com/user/audit_config_change\""
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
}
Positive test num. 5 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
    (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    AND (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
    OR (ProjectOwnership OR projectOwnerInvitee)
    AND (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE" 
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"
    condition_threshold {
      filter = "resource.type=\"gce_instance\" AND metric.type=\"logging.googleapis.com/user/audit_config_change\""
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
}
Positive test num. 6 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
    (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
    AND (ProjectOwnership OR projectOwnerInvitee)
    AND NOT (NOT protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    OR NOT protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert (Log Match)"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"        # test for unusual spacing
    condition_matched_log {
      filter = <<-FILTER
         ( protoPayload.serviceName  = "cloudresourcemanager.googleapis.com" )
        AND
         ( ProjectOwnership   OR projectOwnerInvitee  )
        AND  NOT ( NOT protoPayload.serviceData.policyDelta.bindingDeltas.action   =  "REMOVE"
        OR NOT protoPayload.serviceData.policyDelta.bindingDeltas.role  =   "roles/owner" )
        OR
         (
          protoPayload.serviceData.policyDelta.bindingDeltas.action =   "ADD" AND
            protoPayload.serviceData.policyDelta.bindingDeltas.role   = "roles/owner"
            )
      FILTER
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
}
Positive test num. 7 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
    (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
    AND (ProjectOwnership OR projectOwnerInvitee)
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"
    condition_threshold {
      filter = "resource.type=\"gce_instance\" AND metric.type=\"logging.googleapis.com/user/wrong_reference\""
      # incorrect filter reference
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
}
Positive test num. 8 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
    (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
    AND (ProjectOwnership OR projectOwnerInvitee)
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert (Log Match)"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"
    condition_matched_log {
      filter = <<-FILTER
        (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
        AND (ProjectOwnership)
        OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="Wrong_action"
        AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
        OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
        AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    FILTER
    # incorrect filter
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
  }
}
Positive test num. 9 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
    (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
    AND (ProjectOwnership OR projectOwnerInvitee)
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"
    condition_threshold {
      filter = "resource.type=\"gce_instance\" AND metric.type=\"logging.googleapis.com/user/audit_config_change\""
    }
  }

  # missing notification channels
}
Positive test num. 10 - tf file
resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert (Log Match)"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"        # test for unusual spacing
    condition_matched_log {
      filter = <<-FILTER
         ( protoPayload.serviceName  = "cloudresourcemanager.googleapis.com" )
        AND
         ( ProjectOwnership   OR projectOwnerInvitee  )
        OR   ( protoPayload.serviceData.policyDelta.bindingDeltas.action   =  "REMOVE"
        AND   protoPayload.serviceData.policyDelta.bindingDeltas.role  =   "roles/owner" )
        OR
         (
          protoPayload.serviceData.policyDelta.bindingDeltas.action =   "ADD" AND
            protoPayload.serviceData.policyDelta.bindingDeltas.role   = "roles/owner"
            )
      FILTER
    }
  }
  # missing notification channels
}
Positive test num. 11 - tf file
resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"
    condition_threshold {
      filter = "resource.type=\"gce_instance\" AND metric.type=\"logging.googleapis.com/user/audit_config_change\"" 
    } # missing specific filter
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
}
Positive test num. 12 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
    (protoPayload.serviceName="Wrong_service_name")
    AND (ProjectOwnership OR projectOwnerInvitee)
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
  # incorrect filter
}
Positive test num. 13 - tf file
resource "google_logging_metric" "positive8" {
  name        = "project_ownership_with_not"
  description = "Invalid filter - has NOT before one of the conditions"
  filter = <<-FILTER
    (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
    AND NOT (ProjectOwnership OR projectOwnerInvitee)
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
  # incorrect filter - has NOT before (ProjectOwnership OR projectOwnerInvitee)
}
Positive test num. 14 - tf file
resource "google_logging_metric" "positive9" {
  name        = "project_ownership_with_not_remove"
  description = "Invalid filter - has NOT before the REMOVE condition"
  filter = <<-FILTER
    (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
    AND (ProjectOwnership OR projectOwnerInvitee)
    OR NOT (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
  # incorrect filter - has NOT before the REMOVE condition block
}

Code samples without security vulnerabilities

Negative test num. 1 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
    (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
    AND (ProjectOwnership OR projectOwnerInvitee)
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"
    condition_threshold {
      filter = "resource.type=\"gce_instance\" AND metric.type=\"logging.googleapis.com/user/audit_config_change\""
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
}
Negative test num. 2 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
    (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
    AND (ProjectOwnership OR projectOwnerInvitee)
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert (Log Match)"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"        # test for unusual spacing
    condition_matched_log {
      filter = <<-FILTER
         ( protoPayload.serviceName  = "cloudresourcemanager.googleapis.com" )
        AND
         ( ProjectOwnership   OR projectOwnerInvitee  )
        OR   ( protoPayload.serviceData.policyDelta.bindingDeltas.action   =  "REMOVE"
        AND   protoPayload.serviceData.policyDelta.bindingDeltas.role  =   "roles/owner" )
        OR
         (
          protoPayload.serviceData.policyDelta.bindingDeltas.action =   "ADD" AND
            protoPayload.serviceData.policyDelta.bindingDeltas.role   = "roles/owner"
            )
      FILTER
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
}
Negative test num. 3 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
    (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
    AND (ProjectOwnership OR projectOwnerInvitee)
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"
    condition_threshold {
      filter = "resource.type=\"gce_instance\" AND metric.type=\"logging.googleapis.com/user/audit_config_change\""
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
}

Negative test num. 4 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
  (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
  AND (ProjectOwnership OR projectOwnerInvitee)
  OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
      AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
      AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  OR (protoPayload.methodName="SetIamPolicy")
FILTER

}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"
    condition_threshold {
      filter = "resource.type=\"gce_instance\" AND metric.type=\"logging.googleapis.com/user/audit_config_change\""
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
}
Negative test num. 5 - tf file
resource "google_logging_metric" "audit_config_change_1" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
    (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
    AND (ProjectOwnership OR projectOwnerInvitee)
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
}

resource "google_logging_metric" "audit_config_change_2" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
    (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
    AND (ProjectOwnership OR projectOwnerInvitee)
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
}


resource "google_logging_metric" "audit_config_change_3" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
         ( protoPayload.serviceName  = "cloudresourcemanager.googleapis.com" )
        AND
         ( ProjectOwnership   OR projectOwnerInvitee  )
        OR   ( protoPayload.serviceData.policyDelta.bindingDeltas.action   =  "REMOVE"
        AND   protoPayload.serviceData.policyDelta.bindingDeltas.role  =   "roles/owner" )
        OR
         (
          protoPayload.serviceData.policyDelta.bindingDeltas.action =   "ADD" AND
            protoPayload.serviceData.policyDelta.bindingDeltas.role   = "roles/owner"
            )
      FILTER
}

resource "google_logging_metric" "audit_config_change_4" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
  (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
  AND (ProjectOwnership OR projectOwnerInvitee)
  OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
      AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
      AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  OR (protoPayload.methodName="SetIamPolicy")
FILTER
}
Negative test num. 6 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
  (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
  AND (ProjectOwnership OR projectOwnerInvitee)
  OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
      AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  OR NOT (NOT protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
      OR NOT protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  OR (protoPayload.methodName="SetIamPolicy")
FILTER
}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"
    condition_threshold {
      filter = "resource.type=\"gce_instance\" AND metric.type=\"logging.googleapis.com/user/audit_config_change\""
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
}
Negative test num. 7 - tf file
resource "google_logging_metric" "audit_config_change" {
  name        = "audit_config_change"
  description = "Detects changes to audit configurations via SetIamPolicy"
  filter = <<-FILTER
    (protoPayload.serviceName="cloudresourcemanager.googleapis.com")
    AND NOT (NOT ProjectOwnership AND NOT projectOwnerInvitee)
    OR NOT (NOT protoPayload.serviceData.policyDelta.bindingDeltas.action="REMOVE"
    OR NOT protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
    OR (protoPayload.serviceData.policyDelta.bindingDeltas.action="ADD"
    AND protoPayload.serviceData.policyDelta.bindingDeltas.role="roles/owner")
  FILTER
}

resource "google_monitoring_alert_policy" "audit_config_alert" {
  display_name = "Audit Config Change Alert (Log Match)"

  combiner = "OR"

  conditions {
    display_name = "Audit Config Change Condition"        # test for unusual spacing
    condition_matched_log {
      filter = <<-FILTER
         ( protoPayload.serviceName  = "cloudresourcemanager.googleapis.com" )
        AND
         ( ProjectOwnership   OR projectOwnerInvitee  )
        OR  NOT ( NOT protoPayload.serviceData.policyDelta.bindingDeltas.action   =  "REMOVE"
        OR NOT protoPayload.serviceData.policyDelta.bindingDeltas.role  =   "roles/owner" )
        OR
         (
          protoPayload.serviceData.policyDelta.bindingDeltas.action =   "ADD" AND
            protoPayload.serviceData.policyDelta.bindingDeltas.role   = "roles/owner"
            )
      FILTER
    }
  }

  notification_channels = [google_monitoring_notification_channel.email.id]
}