Back to Checks
azure

Storage account storing Activity Log data is encrypted with a customer-managed key

monitor_storage_account_with_activity_logs_cmk_encrypted
Service: monitorSeverity: medium
OfficialBuilt-inVerified
Categories:encryption
Resource Type:microsoft.storage/storageaccounts

Azure Monitor Activity Logs sent to a Storage account are evaluated to confirm encryption with Customer-Managed Keys (CMK) instead of Microsoft-managed keys.

Risk

Storing activity logs without CMK weakens confidentiality and control of audit data. You lose independent key ownership, limiting rapid rotation/revocation and separation of duties. If storage credentials are compromised, attackers can exfiltrate logs that map resources and changes, aiding targeted attacks and hindering effective incident response.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks monitor_storage_account_with_activity_logs_cmk_encrypted

Recommendation

Encrypt the storage account that holds exported Activity Logs with Customer-Managed Keys via Azure Key Vault or Managed HSM. Apply least privilege to key usage, enforce regular rotation and revocation, and enable soft delete and purge protection. Complement with network isolation and immutable retention for defense in depth.

Remediation

CLI

az storage account update --name <example_resource_name> --resource-group <example_resource_name> --assign-identity --encryption-key-source Microsoft.Keyvault --encryption-key-vault <KeyVaultURI> --encryption-key-name <KeyName>

Terraform

# Storage account encrypted with a customer-managed key (CMK)
resource "azurerm_storage_account" "<example_resource_name>" {
  name                     = "<example_resource_name>"
  resource_group_name      = "<example_resource_name>"
  location                 = "<example_location>"
  account_tier             = "Standard"
  account_replication_type = "LRS"

  identity {
    type = "SystemAssigned" # Required for Storage to access the Key Vault key
  }

  customer_managed_key {
    key_vault_key_id = "<key_vault_key_id>" # CRITICAL: enables CMK by pointing to the Key Vault key
  }
}

NativeIaC

// Storage account encrypted with a customer-managed key (CMK)
resource stg 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: '<example_resource_name>'
  location: resourceGroup().location
  kind: 'StorageV2'
  sku: { name: 'Standard_LRS' }
  identity: { type: 'SystemAssigned' } // Required for Storage to access the Key Vault key
  properties: {
    encryption: {
      keySource: 'Microsoft.Keyvault' // CRITICAL: switches encryption from Microsoft.Storage to CMK
      keyVaultProperties: {
        keyName: '<KeyName>'
        keyVaultUri: '<KeyVaultURI>' // Uses latest key version if not specified
      }
    }
  }
}

Other

1In the Azure portal, go to Storage accounts and open the account used by your Activity Log diagnostic setting
2Select Identity > System assigned > set Status to On > Save
3Go to Settings > Encryption
4Select Customer-managed keys, choose your Key vault and Key, then click Save
5Ensure the storage account's identity has Get, Wrap Key, and Unwrap Key permissions on the key in Key Vault

Check Code

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


class monitor_storage_account_with_activity_logs_cmk_encrypted(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
            )
            for diagnostic_setting in diagnostic_settings:
                for storage_account in storage_client.storage_accounts[subscription_id]:
                    if storage_account.name == diagnostic_setting.storage_account_name:
                        report = Check_Report_Azure(
                            metadata=self.metadata(), resource=storage_account
                        )
                        report.subscription = subscription_id
                        if storage_account.encryption_type == "Microsoft.Storage":
                            report.status = "FAIL"
                            report.status_extended = f"Storage account {storage_account.name} storing activity log in subscription {subscription_name} ({subscription_id}) is not encrypted with Customer Managed Key."
                        else:
                            report.status = "PASS"
                            report.status_extended = f"Storage account {storage_account.name} storing activity log in subscription {subscription_name} ({subscription_id}) is encrypted with Customer Managed Key or not necessary."

                        findings.append(report)

        return findings