Back to Checks
azure

Subscription has an Activity Log diagnostic setting

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

Azure Monitor Diagnostic Settings are configured to export the Activity Log to an external destination (Log Analytics, Storage, Event Hub, or partner).

Risk

Without exporting the Activity Log, control-plane events lack centralization and retention.

Undetected RBAC changes, policy updates, and resource deletions reduce detectability, hinder forensics, and weaken incident response and audit evidence.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks monitor_diagnostic_settings_exists

Recommendation

Enable subscription Diagnostic Settings to send the Activity Log to a trusted destination.

Use immutable storage or a SIEM, enforce coverage with Azure Policy, apply least privilege to log access, include essential categories, and set retention aligned to regulatory needs.

Remediation

CLI

az monitor diagnostic-settings subscription create --subscription <subscription id> --name <example_resource_name> --workspace <log analytics workspace ID> --logs '[{"category":"Administrative","enabled":true}]'

Terraform

# Subscription-level Activity Log diagnostic setting
resource "azurerm_monitor_diagnostic_setting" "<example_resource_name>" {
  name                       = "<example_resource_name>"
  target_resource_id         = "/subscriptions/<subscription id>" # CRITICAL: subscription scope
  log_analytics_workspace_id = "<example_resource_id>"             # CRITICAL: destination workspace

  log {
    category = "Administrative"   # CRITICAL: enable at least one Activity Log category
    enabled  = true
  }
}

NativeIaC

// Subscription-level Activity Log diagnostic setting
resource diag 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
  name: '<example_resource_name>'
  scope: subscription() // CRITICAL: targets the subscription Activity Log
  properties: {
    workspaceId: '<example_resource_id>' // CRITICAL: sends logs to this Log Analytics workspace
    logs: [
      { category: 'Administrative', enabled: true } // CRITICAL: enables at least one Activity Log category
    ]
  }
}

Other

1In the Azure portal, go to Subscriptions and select your subscription
2Open Monitoring > Activity log, then click Diagnostic settings
3Click + Add diagnostic setting and enter a name
4Under Destination details, select Send to Log Analytics workspace and choose your workspace
5Under Categories, select Administrative
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_settings_exists(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
            )
            if diagnostic_settings:
                # At least one diagnostic setting exists - report on the first one
                diagnostic_setting = diagnostic_settings[0]
                report = Check_Report_Azure(
                    metadata=self.metadata(), resource=diagnostic_setting
                )
                report.subscription = subscription_id
                report.status = "PASS"
                report.status_extended = f"Diagnostic setting {diagnostic_setting.name} found in subscription {subscription_name} ({subscription_id})."
            else:
                # No diagnostic settings - report on subscription
                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 settings found in subscription {subscription_name} ({subscription_id})."

            findings.append(report)

        return findings