Back to Checks
azure

Subscription has an Activity Log alert for policy assignment deletion

monitor_alert_delete_policy_assignment
Service: monitorSeverity: high
OfficialBuilt-inVerified
Categories:logging
Resource Type:microsoft.insights/activitylogalerts

Azure Monitor Activity log alerts for policy assignment deletions using the Microsoft.Authorization/policyAssignments/delete operation at subscription scope

Risk

Without this alert, policy assignment deletions can go unnoticed, eroding configuration integrity and enabling governance drift. Malicious or accidental changes may remove guardrails, increasing exposure and threatening confidentiality of protected resources.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks monitor_alert_delete_policy_assignment

Recommendation

  • Configure an activity log alert for Microsoft.Authorization/policyAssignments/delete and route to an action group.
  • Enforce least privilege and separation of duties for policy changes and require approvals.
  • Integrate alerts with your SIEM and define playbooks for rapid response.

Remediation

CLI

az monitor activity-log alert create --resource-group <example_resource_name> --name <example_resource_name> --scopes "/subscriptions/<example_resource_id>" --condition "operationName=Microsoft.Authorization/policyAssignments/delete" --location global

Terraform

# Activity Log alert for Policy Assignment deletion
resource "azurerm_monitor_activity_log_alert" "<example_resource_name>" {
  name                = "<example_resource_name>"
  resource_group_name = "<example_resource_name>"
  scopes              = ["/subscriptions/<example_resource_id>"]

  criteria {
    operation_name = "Microsoft.Authorization/policyAssignments/delete" # CRITICAL: alerts on policy assignment deletion
  }
}

NativeIaC

// Activity Log alert for Policy Assignment deletion
resource alert 'Microsoft.Insights/activityLogAlerts@2020-10-01' = {
  name: '<example_resource_name>'
  location: 'Global'
  properties: {
    scopes: [
      '/subscriptions/<example_resource_id>'
    ]
    condition: {
      allOf: [
        {
          field: 'operationName'
          equals: 'Microsoft.Authorization/policyAssignments/delete' // CRITICAL: alerts on policy assignment deletion
        }
      ]
    }
    actions: {
      actionGroups: [] // Required property; empty keeps rule minimal
    }
  }
}

Other

1In Azure Portal, go to Monitor > Alerts > Alert rules
2Click + Create > Alert rule
3Scope: Select your subscription and click Apply
4Condition: Choose Activity log, then set Operation name equals "Microsoft.Authorization/policyAssignments/delete"
5Actions: Skip (optional)
6Details: Enter a name and set Enable alert rule upon creation
7Click Create

Check Code

from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.monitor.lib.monitor_alerts import check_alert_rule
from prowler.providers.azure.services.monitor.monitor_client import monitor_client


class monitor_alert_delete_policy_assignment(Check):
    def execute(self) -> Check_Report_Azure:
        findings = []

        for (
            subscription_id,
            activity_log_alerts,
        ) in monitor_client.alert_rules.items():
            subscription_name = monitor_client.subscriptions.get(
                subscription_id, subscription_id
            )
            for alert_rule in activity_log_alerts:
                if check_alert_rule(
                    alert_rule, "Microsoft.Authorization/policyAssignments/delete"
                ):
                    report = Check_Report_Azure(
                        metadata=self.metadata(), resource=alert_rule
                    )
                    report.subscription = subscription_id
                    report.status = "PASS"
                    report.status_extended = f"There is an alert configured for deleting policy assignment in subscription {subscription_name} ({subscription_id})."
                    break
            else:
                report = Check_Report_Azure(metadata=self.metadata(), resource={})
                report.subscription = subscription_id
                report.resource_name = subscription_id
                report.resource_id = f"/subscriptions/{subscription_id}"
                report.status = "FAIL"
                report.status_extended = f"There is not an alert for deleting policy assignment in subscription {subscription_name} ({subscription_id})."

            findings.append(report)

        return findings