Back to Checks
azure

Key Vault has at least one diagnostic setting with audit logging enabled

keyvault_logging_enabled
Service: keyvaultSeverity: high
OfficialBuilt-inVerified
Categories:logging
Resource Type:microsoft.keyvault/vaults

Azure Key Vault diagnostic settings capture audit logs (AuditEvent) when the AuditEvent category is enabled, or when category groups audit and allLogs are enabled, and routed to a supported destination. Logged events include management and data-plane operations on vaults, keys, secrets, and certificates.

Risk

Without Key Vault audit logging, access and changes to keys, secrets, and certificates are untracked.

Attackers can misuse keys to decrypt data, alter or delete crypto material, and evade detection-eroding confidentiality and integrity and delaying incident response.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks keyvault_logging_enabled

Recommendation

Enable diagnostic settings to collect AuditEvent logs and send them to a central sink. Apply least privilege to log access, enforce secure retention/immutability, monitor with alerts for anomalous operations, and use separation of duties to prevent logging bypass.

Remediation

CLI

az monitor diagnostic-settings create --name <example_resource_name> --resource <example_resource_id> --workspace <example_resource_id> --logs '[{"category":"AuditEvent","enabled":true}]'

Terraform

# Enable AuditEvent diagnostic logs on Key Vault
resource "azurerm_monitor_diagnostic_setting" "<example_resource_name>" {
  name                       = "<example_resource_name>"
  target_resource_id         = "<example_resource_id>"
  log_analytics_workspace_id = "<example_resource_id>"

  enabled_log {
    category = "AuditEvent"
  }
}

NativeIaC

// Enable Key Vault AuditEvent diagnostic logs
param keyVaultName string
param workspaceId string

resource kv 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
  name: keyVaultName
}

resource diag 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
  name: '<example_resource_name>'
  scope: kv
  properties: {
    workspaceId: workspaceId
    logs: [
      {
        category: 'AuditEvent'
        enabled: true
      }
    ]
  }
}

Other

1In Azure Portal, go to your Key Vault > Monitoring > Diagnostic settings
2Click Add diagnostic setting
3Enable AuditEvent audit logs, or select the audit and allLogs category groups
4Choose a destination (e.g., Send to Log Analytics workspace) and select the workspace
5Click Save

Check Code

from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.keyvault.keyvault_client import keyvault_client


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

        for subscription_id, key_vaults in keyvault_client.key_vaults.items():
            subscription_name = keyvault_client.subscriptions.get(
                subscription_id, subscription_id
            )
            for keyvault in key_vaults:
                report = Check_Report_Azure(metadata=self.metadata(), resource=keyvault)
                report.subscription = subscription_id
                report.status = "FAIL"
                report.status_extended = f"Key Vault {keyvault.name} in subscription {subscription_name} ({subscription_id}) does not have a diagnostic setting with audit logging."
                for diagnostic_setting in keyvault.monitor_diagnostic_settings or []:
                    has_audit_category = False
                    has_audit_group = False
                    has_all_logs = False
                    for log in diagnostic_setting.logs:
                        if log.category == "AuditEvent" and log.enabled:
                            has_audit_category = True
                        if log.category_group == "audit" and log.enabled:
                            has_audit_group = True
                        if log.category_group == "allLogs" and log.enabled:
                            has_all_logs = True
                    if has_audit_category or (has_audit_group and has_all_logs):
                        report.status = "PASS"
                        report.status_extended = f"Key Vault {keyvault.name} in subscription {subscription_name} ({subscription_id}) has a diagnostic setting with audit logging."
                        break
                findings.append(report)

        return findings