Subscription has a diagnostic setting capturing Administrative, Security, Alert, and Policy categories
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 Cloudprowler azure --checks monitor_diagnostic_setting_with_appropriate_categoriesRecommendation
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
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 findingsReferences
- https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/diagnostic-settings
- https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/Monitor/diagnostic-setting-categories.html
- https://learn.microsoft.com/en-us/azure/storage/common/manage-storage-analytics-logs?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json&tabs=azure-portal