Back to Checks
azure

Subscription has an Activity Log alert for Network Security Group create or update operations

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

Azure Monitor Activity Log alert monitors Network Security Group changes via the Microsoft.Network/networkSecurityGroups/write operation to capture create/update events across the subscription

Risk

Lack of alerting on NSG changes allows unauthorized network policy modifications to go unnoticed. Adversaries or mistakes could open ports, reduce segmentation, and enable lateral movement, impacting data confidentiality and service availability through exposure or disruption of critical traffic

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks monitor_alert_create_update_nsg

Recommendation

Implement a subscription-wide Activity Log alert for NSG change operations and route notifications to an action group for rapid triage.

Apply least privilege for change tooling, enforce change management, and add complementary alerts for Microsoft.Network/networkSecurityGroups/securityRules/write and .../delete. Integrate with SIEM for correlation

Remediation

CLI

az monitor activity-log alert create --resource-group '<example_resource_name>' --name '<example_resource_name>' --scopes '/subscriptions/<subscription ID>' --condition "category=Administrative and operationName=Microsoft.Network/networkSecurityGroups/write" --location global

Terraform

# Activity Log alert for NSG create/update
resource "azurerm_monitor_activity_log_alert" "<example_resource_name>" {
  name                = "<example_resource_name>"
  resource_group_name = "<example_resource_name>"
  scopes              = ["/subscriptions/<subscription_id>"]

  criteria {
    category       = "Administrative"
    operation_name = "Microsoft.Network/networkSecurityGroups/write" # Critical: triggers on NSG create/update
  }
}

NativeIaC

// Activity Log alert for NSG create/update
resource alert 'Microsoft.Insights/activityLogAlerts@2020-10-01' = {
  name: '<example_resource_name>'
  location: 'Global'
  properties: {
    scopes: [ subscription().id ]
    condition: {
      allOf: [
        { field: 'category', equals: 'Administrative' }
        { field: 'operationName', equals: 'Microsoft.Network/networkSecurityGroups/write' } // Critical: triggers on NSG create/update
      ]
    }
    enabled: true // Ensures the alert is active
  }
}

Other

1In the Azure portal, go to Monitor > Alerts > Alert rules > Create
2Scope: Select your subscription and click Apply
3Condition: Choose Activity log, set Category to Administrative, set Operation name to Microsoft.Network/networkSecurityGroups/write, then Done
4Actions: Skip (optional)
5Details: Name the rule and set Region to Global, ensure Enable upon creation is checked
6Review + create > 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_create_update_nsg(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.Network/networkSecurityGroups/write"
                ):
                    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 creating/updating Network Security Groups 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 creating/updating Network Security Groups in subscription {subscription_name} ({subscription_id})."

            findings.append(report)

        return findings