Back to blog
AzureBest PracticesCloud SecurityMonitoring & LoggingOperations & Compliance

Key Vault Has No Diagnostic Settings: Why It Matters and How to Fix It

Learn why an Azure Key Vault with no diagnostic settings is a security blind spot, and how to enable AuditEvent logging with CLI, Terraform, and Azure Policy.

TL;DR

This check flags Azure Key Vaults that have no diagnostic settings, meaning access and audit events are never sent to a Log Analytics workspace, storage account, or event hub. Without those logs you cannot detect secret theft or prove what happened during an incident. Fix it by attaching a diagnostic setting that ships AuditEvent logs to a retained destination.

Key Vault is where a lot of your most sensitive material lives: TLS certificates, database connection strings, storage account keys, encryption keys for disks and databases. When something queries a secret or a key, that event is interesting. Was it your app's managed identity, or was it a service principal nobody recognizes pulling every secret at 3am? You can only answer that question if the vault is logging.

The Key Vault Has No Diagnostic Settings check looks for vaults where no diagnostic setting exists at all. No logs are being emitted, so the audit trail for one of your most critical resources is simply empty.


What this check detects

Every Azure Key Vault can emit diagnostic logs through Azure Monitor diagnostic settings. The relevant log category is AuditEvent, which records every operation against the vault: secret reads, key wrap/unwrap operations, certificate retrievals, access policy changes, and management plane activity.

This check fails when a vault has zero diagnostic settings configured. That means none of those events are being routed anywhere. The vault is operating, secrets are being read and written, but there is no record of any of it beyond the short-lived Activity Log entries for management operations (which do not cover data plane access like "secret X was read").

Note: The Azure Activity Log captures control plane events (creating a vault, changing access policies) but it does not capture data plane events like reading a secret value. Data plane auditing only exists if you have wired up a diagnostic setting with the AuditEvent category. This is the single most common gap people miss.


Why it matters

A Key Vault with no logging is a blind spot around your most valuable secrets. Here is what that costs you in practice.

You cannot detect credential theft

Suppose an attacker compromises an application identity or steals a service principal credential. One of the first things they will do is enumerate and read secrets from any vault that identity can reach. If diagnostics are off, that bulk read of every connection string and API key generates no log you can alert on. The first sign of trouble might be a breach notification from a downstream system weeks later.

You cannot do incident response

When an incident does happen, the investigation question is always "what did they access?" Without AuditEvent logs you cannot answer it. You are forced to assume every secret in the vault is compromised and rotate all of them, which for a busy vault can mean dozens of certificates and connection strings and a painful coordinated rollout.

You fail compliance audits

SOC 2, PCI DSS, ISO 27001, and HIPAA all expect audit logging on systems that store cryptographic material and credentials. A Key Vault with no diagnostic settings is a finding waiting to be written up. PCI DSS Requirement 10 in particular is explicit about logging access to systems that handle cardholder data, and secrets stored in Key Vault frequently sit on that path.

Danger: If you turn diagnostics on after a suspected breach, you only capture events from that point forward. There is no retroactive log. The window before you enabled logging is gone permanently. This is why the fix needs to happen before you need it, not during the incident.


How to fix it

The fix is to create a diagnostic setting on the vault that sends at least the AuditEvent category to a durable destination. A Log Analytics workspace is the best target because it lets you query and alert. You can also fan out to a storage account for cheap long-term retention and to an event hub for streaming into a SIEM.

Option 1: Azure CLI

First grab the resource ID of the vault and the workspace you want logs to land in.

VAULT_ID=$(az keyvault show \
  --name my-keyvault \
  --resource-group my-rg \
  --query id -o tsv)

WORKSPACE_ID=$(az monitor log-analytics workspace show \
  --resource-group my-monitoring-rg \
  --workspace-name my-law \
  --query id -o tsv)

Now create the diagnostic setting. This enables both log categories and the metrics.

az monitor diagnostic-settings create \
  --name kv-audit-to-law \
  --resource "$VAULT_ID" \
  --workspace "$WORKSPACE_ID" \
  --logs '[
    {"category": "AuditEvent", "enabled": true},
    {"category": "AzurePolicyEvaluationDetails", "enabled": true}
  ]' \
  --metrics '[{"category": "AllMetrics", "enabled": true}]'

Warning: Sending logs to Log Analytics has an ingestion and retention cost based on data volume. For a busy vault this is usually small, but if you have hundreds of vaults it adds up. Consider sending high-volume vaults to a cheaper storage account for archival and reserving Log Analytics for vaults you actively monitor and alert on.

Option 2: Azure Portal

  1. Open the Key Vault in the Azure Portal.
  2. Under Monitoring in the left menu, select Diagnostic settings.
  3. Click Add diagnostic setting.
  4. Give it a name like kv-audit-to-law.
  5. Under Logs, tick audit (or allLogs) and AllMetrics.
  6. Under Destination details, choose Send to Log Analytics workspace and pick your workspace.
  7. Click Save.

Option 3: Terraform

If you manage infrastructure as code, define the diagnostic setting alongside the vault so it can never be created without logging.

resource "azurerm_monitor_diagnostic_setting" "kv_audit" {
  name                       = "kv-audit-to-law"
  target_resource_id         = azurerm_key_vault.this.id
  log_analytics_workspace_id = azurerm_log_analytics_workspace.this.id

  enabled_log {
    category = "AuditEvent"
  }

  enabled_log {
    category = "AzurePolicyEvaluationDetails"
  }

  metric {
    category = "AllMetrics"
    enabled  = true
  }
}

Option 4: Bicep

resource kvDiag 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
  name: 'kv-audit-to-law'
  scope: keyVault
  properties: {
    workspaceId: logAnalyticsWorkspace.id
    logs: [
      {
        category: 'AuditEvent'
        enabled: true
      }
    ]
    metrics: [
      {
        category: 'AllMetrics'
        enabled: true
      }
    ]
  }
}

Tip: Once logs are flowing, set up a real alert. A useful one is a spike in SecretGet operations from a single identity, which is a strong signal of credential abuse. You can build this as a Log Analytics alert rule against the AzureDiagnostics table.

Here is a KQL query you can use as the basis for that alert:

AzureDiagnostics
| where ResourceType == "VAULTS"
| where OperationName == "SecretGet"
| summarize SecretReads = count() by CallerIPAddress, identity_claim_appid_g, bin(TimeGenerated, 5m)
| where SecretReads > 50
| order by SecretReads desc

How to prevent it from happening again

Fixing one vault by hand does not stop the next one from being created without logging. Make diagnostics the default through policy and pipeline gates.

Azure Policy with DeployIfNotExists

Azure ships a built-in policy that deploys a diagnostic setting to any Key Vault that lacks one. Assign it at the subscription or management group level and any new vault gets logging automatically. The relevant policy is:

"Deploy Diagnostic Settings for Key Vault to Log Analytics workspace"

Assign it with the CLI and point it at your workspace:

az policy assignment create \
  --name deploy-kv-diagnostics \
  --display-name "Deploy Key Vault diagnostics to Log Analytics" \
  --scope "/subscriptions/$SUBSCRIPTION_ID" \
  --policy "ddc0a39c-7e0a-4e3d-ae5a-..." \
  --params "{\"logAnalytics\": {\"value\": \"$WORKSPACE_ID\"}}" \
  --location eastus \
  --mi-system-assigned \
  --role "Contributor"

Note: A DeployIfNotExists policy needs a managed identity with permission to create diagnostic settings and to write to the target workspace. The --mi-system-assigned flag creates that identity, and you grant it a role with --role. Run a remediation task afterwards to fix vaults that already exist, since the policy only auto-applies to new or updated resources.

Catch it in CI/CD with policy-as-code

If your vaults are defined in Terraform or Bicep, scan the plan before it applies. Tools like Checkov, tfsec, or Conftest can fail a pull request when a Key Vault has no associated diagnostic setting. A simple Checkov gate in your pipeline:

checkov -d ./infra --framework terraform \
  --check CKV2_AZURE_32  # Key Vault diagnostic logs enabled

Tip: Combine both layers. Policy-as-code in CI catches problems before deploy and gives developers fast feedback, while Azure Policy in the cloud catches anything created outside your pipelines (portal clicks, scripts, other teams). Belt and suspenders.


Best practices

  • Always send AuditEvent logs. This is the category that records data plane access. Metrics alone are not enough for security investigations.
  • Use a centralized Log Analytics workspace. Pointing every vault across subscriptions at one workspace makes cross-environment querying and alerting far simpler than chasing logs in separate buckets.
  • Add a storage account destination for long retention. Log Analytics retention can be expensive past 30 to 90 days. Archive to immutable storage for the multi-year retention some compliance frameworks require.
  • Alert, do not just collect. Logs you never look at do not stop a breach. Build alerts for anomalous secret reads, access policy changes, and failed authorization attempts.
  • Pair logging with least privilege. Diagnostics tell you who accessed what. RBAC and access policies control who can access what. Tight access policies reduce the noise and the blast radius.
  • Enable soft delete and purge protection. Logging records destructive actions, but purge protection prevents an attacker from permanently destroying secrets and keys in the first place.

A Key Vault without diagnostic settings is one of those quiet gaps that nobody notices until they desperately need the logs and find there are none. The fix takes a few minutes per vault and is fully automatable, so there is no good reason to leave any vault unmonitored. Turn on AuditEvent, ship it to a workspace you actually watch, and enforce it with policy so the next vault is covered by default.