Back to Checks
Prowlerprowler-provider-azure
Azure Storage account uses customer-managed keys (CMKs) for encryption
storage_ensure_encryption_with_customer_managed_keys
Service: storageSeverity: high
OfficialBuilt-inVerified
Categories:encryption
Resource Type:microsoft.storage/storageaccounts
Azure Storage accounts use customer-managed keys (CMK) from Key Vault/Managed HSM for service-side encryption of data at rest, rather than platform-managed keys (encryption_type=Microsoft.Keyvault).
Risk
Without CMK, keys are provider-controlled, reducing confidentiality and governance.
- Cannot promptly revoke access during incidents
- No custom rotation or separation of duties
- Limited key-use auditing This weakens data sovereignty and hinders effective crypto-shredding.
Run this check with Prowler
Run in Prowler CloudRun
prowler azure --checks storage_ensure_encryption_with_customer_managed_keysRecommendation
Adopt CMK with keys in Key Vault or Managed HSM. Enforce least privilege for the storage identity, regular key rotation, and separation of duties between key custodians and operators. Audit key usage, enable tamper-resistant key protection (soft-delete/purge protection), and plan for key revocation/crypto-shredding.
Remediation
CLI
az storage account update --name <STORAGE_ACCOUNT_NAME> --resource-group <RESOURCE_GROUP> --encryption-key-name <KEY_NAME> --encryption-key-source Microsoft.Keyvault --encryption-key-vault <KEY_VAULT_URI>Terraform
# Configure a Storage Account to use Customer-Managed Keys (CMK)
resource "azurerm_storage_account" "<example_resource_name>" {
name = "<example_resource_name>"
resource_group_name = "<example_resource_name>"
location = "<location>"
account_tier = "Standard"
account_replication_type = "LRS"
identity {
type = "SystemAssigned" # CRITICAL: allow storage account to access Key Vault
}
customer_managed_key {
key_vault_key_id = "<example_resource_id>" # CRITICAL: Key Vault key ID enabling CMK (passes the check)
}
}NativeIaC
// Configure a Storage Account to use Customer-Managed Keys (CMK)
resource sa 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: '<example_resource_name>'
location: '<location>'
sku: { name: 'Standard_LRS' }
kind: 'StorageV2'
identity: {
type: 'SystemAssigned' // CRITICAL: required so the storage account can access the key vault
}
properties: {
encryption: {
keySource: 'Microsoft.Keyvault' // CRITICAL: switches encryption to CMK (Prowler checks for this)
keyVaultProperties: {
keyName: '<key_name>' // required key name
keyVaultUri: 'https://<example_resource_name>.vault.azure.net/' // required Key Vault URI
}
}
}
}Other
1In the Azure portal, open your Storage account
2Go to Settings > Encryption (or Security + networking > Encryption)
3Select Customer-managed keys
4Click Select a key vault and key, choose your Key Vault and key
5If prompted, enable System-assigned managed identity and grant the key permissions get, wrapKey, unwrapKey
6Click Save
Check Code
from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.storage.storage_client import storage_client
class storage_ensure_encryption_with_customer_managed_keys(Check):
def execute(self) -> Check_Report_Azure:
findings = []
for subscription, storage_accounts in storage_client.storage_accounts.items():
subscription_name = storage_client.subscriptions.get(
subscription, subscription
)
for storage_account in storage_accounts:
report = Check_Report_Azure(
metadata=self.metadata(), resource=storage_account
)
report.subscription = subscription
report.status = "PASS"
report.status_extended = f"Storage account {storage_account.name} from subscription {subscription_name} ({subscription}) encrypts with CMKs."
if storage_account.encryption_type != "Microsoft.Keyvault":
report.status = "FAIL"
report.status_extended = f"Storage account {storage_account.name} from subscription {subscription_name} ({subscription}) does not encrypt with CMKs."
findings.append(report)
return findings