Back to Checks
azure

Subscription has a diagnostic setting capturing Administrative, Security, Alert, and Policy categories

monitor_diagnostic_setting_with_appropriate_categories
Service: monitorSeverity: high
OfficialBuilt-inVerified
Categories:logging
Resource Type:microsoft.resources/subscriptions

Azure Monitor Diagnostic Settings capture control-plane events at the subscription level. This evaluates whether at least one setting collects the categories: Administrative, Security, Policy, and Alert.

Risk

Without these categories, critical control-plane actions may go unrecorded. Attackers could change policies, roles, or alerts unnoticed, enabling privilege escalation and resource tampering. This erodes integrity, threatens confidentiality, and weakens availability and incident response.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks monitor_diagnostic_setting_with_appropriate_categories

Recommendation

Collect Administrative, Security, Policy, and Alert via a subscription diagnostic setting and route them to a centralized, tamper-resistant destination. Enforce least privilege on log access, set retention, and create alerts for high-risk changes as part of defense in depth.

Remediation

CLI

az monitor diagnostic-settings subscription create --name <example_resource_name> --workspace <example_resource_id> --logs '[{"category":"Administrative","enabled":true},{"category":"Security","enabled":true},{"category":"Alert","enabled":true},{"category":"Policy","enabled":true}]'

Terraform

# Subscription Activity Log diagnostic setting capturing required categories
resource "azurerm_monitor_diagnostic_setting" "example" {
  name                       = "<example_resource_name>"
  target_resource_id         = "/subscriptions/<example_resource_id>" # Critical: scope set to the subscription
  log_analytics_workspace_id = "<example_resource_id>"                 # Critical: destination workspace

  enabled_log { category = "Administrative" } # Critical: required category
  enabled_log { category = "Security" }      # Critical: required category
  enabled_log { category = "Alert" }         # Critical: required category
  enabled_log { category = "Policy" }        # Critical: required category
}

NativeIaC

// Create a subscription-level diagnostic setting capturing required categories
targetScope = 'subscription'

resource diag 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
  name: '<example_resource_name>'
  properties: {
    workspaceId: '<example_resource_id>' // Critical: send Activity Log to this Log Analytics workspace
    logs: [
      { category: 'Administrative', enabled: true } // Critical: required category
      { category: 'Security',      enabled: true } // Critical: required category
      { category: 'Alert',         enabled: true } // Critical: required category
      { category: 'Policy',        enabled: true } // Critical: required category
    ]
  }
}

Other

1In Azure portal, go to Monitor > Activity log
2Click Diagnostic settings > Add diagnostic setting
3Name the setting
4Under Categories, check: Administrative, Security, Alert, Policy
5Under Destination, select Send to Log Analytics workspace and choose your workspace
6Click Save

Check Code

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


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

        for (
            subscription_id,
            diagnostic_settings,
        ) in monitor_client.diagnostics_settings.items():
            subscription_name = monitor_client.subscriptions.get(
                subscription_id, subscription_id
            )
            compliant_setting = None

            for diagnostic_setting in diagnostic_settings:
                administrative_enabled = False
                security_enabled = False
                alert_enabled = False
                policy_enabled = False

                for log in diagnostic_setting.logs:
                    if log.category == "Administrative" and log.enabled:
                        administrative_enabled = True
                    if log.category == "Security" and log.enabled:
                        security_enabled = True
                    if log.category == "Alert" and log.enabled:
                        alert_enabled = True
                    if log.category == "Policy" and log.enabled:
                        policy_enabled = True

                if (
                    administrative_enabled
                    and security_enabled
                    and alert_enabled
                    and policy_enabled
                ):
                    compliant_setting = diagnostic_setting
                    break

            if compliant_setting:
                report = Check_Report_Azure(
                    metadata=self.metadata(), resource=compliant_setting
                )
                report.subscription = subscription_id
                report.status = "PASS"
                report.status_extended = f"Diagnostic setting {compliant_setting.name} captures appropriate categories in subscription {subscription_name} ({subscription_id})."
            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"No diagnostic setting captures all appropriate categories (Administrative, Security, Alert, Policy) in subscription {subscription_name} ({subscription_id})."

            findings.append(report)

        return findings