Skip to main content

Theoretical Foundation: Configure Storage Account Encryption


1. Initial Intuition​

Imagine you store confidential documents in a safe. Anyone who has the safe's key can open and read the documents. Now imagine that before putting the documents in the safe, you scramble the text of each page with a secret code. Even if someone steals the entire safe and forces it open, the documents are unreadable without the code to decode them.

Encryption at rest is exactly that: data is transformed into an unreadable format before being written to disk. When an authorized system needs to read the data, it is automatically decoded in memory.

In Azure Storage, all encryption at rest is automatic, mandatory, and transparent. It cannot be disabled. What you control is who owns and manages the keys used in this process.


2. Context​

2.1 Why encryption at rest exists​

Without encryption at rest, an attacker who gained physical access to datacenter disks could read the data directly. With encryption, physical disks contain only scrambled data, worthless without the corresponding keys.

In Azure, Storage Account encryption protects against:

  • Unauthorized physical access to datacenter hardware
  • Physical disk exfiltration
  • Regulatory requirements (LGPD, GDPR, HIPAA, PCI-DSS) that require encrypted data at rest

2.2 What Storage Account encryption covers​

ServiceEncrypted?
Blob StorageYes
Azure FilesYes
Queue StorageYes
Table StorageYes
Object metadataYes
Data in transit (HTTPS)Yes (separate configuration)

Important point: Azure Storage encryption at rest is different from VM disk encryption (Azure Disk Encryption / Server-Side Encryption of managed disks). They are independent mechanisms.


3. Concept Building​

3.1 How encryption works internally​

Azure uses AES-256, one of the most robust cryptographic standards available. The process involves two levels of keys:

Data Encryption Key (DEK): Key that encrypts the data itself. Each object (blob, file, etc.) can have its own DEK.

Key Encryption Key (KEK): Key that encrypts the DEK. This is the level where customer control is applied.

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

This two-layer model means that:

  • If you rotate or revoke the KEK, all data becomes inaccessible without needing to re-encrypt every byte.
  • The data itself (protected by the DEK) doesn't need to be moved or re-encrypted when the KEK changes.

3.2 The two key management models​

Microsoft Managed Keys (MMK)​

What it is: Microsoft automatically generates, stores, and rotates the KEKs. You have no access to them.

Analogy: It's like using the hotel safe. The hotel manages the combination, you use the service without worrying about the master key.

Characteristics:

  • Enabled by default on all Storage Accounts
  • No additional management cost
  • Automatic rotation managed by Microsoft
  • No visibility or control over keys

Customer Managed Keys (CMK)​

What it is: You create and manage the KEK in an Azure Key Vault or Azure Managed HSM. Azure Storage uses this external key to encrypt the DEKs, but never stores your key permanently.

Analogy: It's like having a bank safe where only you have the master key. The bank can access the contents when you allow it, but if you revoke access, the bank can no longer open the safe.

Characteristics:

  • Full control over key lifecycle
  • Ability to revoke access immediately
  • Complete audit of key usage (who used it, when)
  • Customer-controlled key rotation
  • Additional cost: Key Vault and key operations are charged

Customer Provided Keys (CPK)​

What it is: The customer provides the key directly in each HTTP request to Storage. The key is never stored in Azure.

Analogy: It's like you personally bringing the key every time you want to open the safe. The bank never keeps your key, but you need to bring it every time.

Characteristics:

  • Key exists only in memory during the request
  • Not stored in Azure
  • Management completely outside Azure
  • Applicable only to Blob Storage operations
  • Requires implementation in application code (not configurable in portal)

3.3 Encryption scope: account vs infrastructure​

Azure offers two scopes where CMK can be applied:

Account scope (CMK default): One Key Vault key encrypts the entire Storage Account data.

Encryption scope (Encryption Scope): Allows using different keys per container or per individual blob, within the same Storage Account.

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

Encryption Scopes allow cryptographic isolation within the same Storage Account. HR department and finance data can coexist in the same Storage Account with completely different keys.


3.4 Infrastructure Encryption (Double Encryption)​

For compliance scenarios that require multiple encryption layers, Azure offers Infrastructure Encryption, which adds a second encryption layer at the infrastructure level (hardware/hypervisor), independent of service encryption.

Result: data is encrypted twice with completely independent algorithms and keys.

LayerAlgorithmKeys
Layer 1 (Storage Service)AES-256MMK or CMK
Layer 2 (Infrastructure)AES-256Always Microsoft-managed

Important: Infrastructure Encryption must be enabled at Storage Account creation time. It cannot be enabled later.


4. Structural View: Write and Read Flow​

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

5. Practical Operation​

5.1 Prerequisites for CMK​

To use Customer Managed Keys, you need:

  1. Azure Key Vault with the following configurations:

    • Soft Delete enabled (mandatory)
    • Purge Protection enabled (mandatory for CMK in Storage)
    • Configured in the same region as the Storage Account (recommended)
  2. Managed Identity assigned to the Storage Account so it can access the Key Vault without explicit credentials.

  3. Key Vault permissions for the Storage Account identity:

    • Get (get key)
    • Wrap Key (encrypt DEK with KEK)
    • Unwrap Key (decrypt DEK with KEK)

5.2 Types of managed identity for CMK​

TypeDescriptionWhen to use
System-assigned Managed IdentityCreated and linked to the Storage Account. Deleted along with the account.Simple scenarios, one account per Key Vault
User-assigned Managed IdentityCreated independently, can be shared between resources.Multiple Storage Accounts using the same Key Vault

5.3 Key rotation​

When you rotate the KEK in Key Vault (create a new key version), Azure Storage needs to be notified to start using the new version.

Automatic rotation: Configure the Storage Account to use the latest version of the key. Azure automatically detects new versions and adopts them.

Manual rotation: Configure the Storage Account to use a specific version of the key. You control exactly when the new version is adopted.

Critical behavior on revocation: If you revoke the Storage Account identity's access to Key Vault (or delete the key), the Storage Account becomes inaccessible immediately. Reads and writes fail with authorization error. This is intentional and is the "kill switch" mechanism that CMK provides.


5.4 Encryption Scopes: lifecycle​

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

Critical point: Encryption Scopes cannot be deleted, only disabled. A disabled scope makes blobs that use it inaccessible, but doesn't delete them. Re-enabling the scope restores access.


6. Implementation Methods​

6.1 Enabling CMK via Azure Portal​

Steps:

  1. Create Key Vault with Soft Delete and Purge Protection
  2. Create a key in Key Vault (RSA 2048, 3072, or 4096)
  3. In Storage Account: Security + networking > Encryption
  4. Select "Customer-managed keys"
  5. Select Key Vault and key
  6. Assign or create Managed Identity for the account
  7. Save

The portal automatically configures Key Vault permissions for the Storage Account identity when you select "Grant access" during the process.


6.2 Azure CLI​

Creating Key Vault with mandatory protections:

az keyvault create \
--name myKeyVault \
--resource-group myRG \
--location eastus \
--enable-soft-delete true \
--enable-purge-protection true

Creating RSA key:

az keyvault key create \
--vault-name myKeyVault \
--name myStorageKey \
--kty RSA \
--size 2048

Assigning System-assigned Identity to Storage Account:

az storage account update \
--name mystorageaccount \
--resource-group myRG \
--assign-identity

Getting the Principal ID of the identity:

PRINCIPAL_ID=$(az storage account show \
--name mystorageaccount \
--resource-group myRG \
--query identity.principalId \
--output tsv)

Granting Key Vault permissions:

az keyvault set-policy \
--name myKeyVault \
--object-id $PRINCIPAL_ID \
--key-permissions get wrapKey unwrapKey

Configuring CMK on Storage Account:

KEY_URI=$(az keyvault key show \
--vault-name myKeyVault \
--name myStorageKey \
--query key.kid \
--output tsv)

az storage account update \
--name mystorageaccount \
--resource-group myRG \
--encryption-key-source Microsoft.Keyvault \
--encryption-key-uri $KEY_URI

6.3 Azure PowerShell​

# Create identity and get principal
$storageAccount = Set-AzStorageAccount `
-ResourceGroupName "myRG" `
-Name "mystorageaccount" `
-AssignIdentity

# Configure Key Vault permissions
Set-AzKeyVaultAccessPolicy `
-VaultName "myKeyVault" `
-ObjectId $storageAccount.Identity.PrincipalId `
-PermissionsToKeys get, wrapKey, unwrapKey

# Get key
$key = Get-AzKeyVaultKey `
-VaultName "myKeyVault" `
-Name "myStorageKey"

# Configure CMK
Set-AzStorageAccount `
-ResourceGroupName "myRG" `
-Name "mystorageaccount" `
-KeyvaultEncryption `
-KeyName $key.Name `
-KeyVersion $key.Version `
-KeyVaultUri "https://myKeyVault.vault.azure.net"

6.4 Bicep​

// Key Vault with mandatory protections
resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
name: 'myKeyVault'
location: location
properties: {
sku: { family: 'A', name: 'standard' }
tenantId: subscription().tenantId
enableSoftDelete: true
enablePurgeProtection: true
accessPolicies: []
}
}

// Storage Account with system-assigned identity and CMK
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: 'mystorageaccount'
location: location
sku: { name: 'Standard_LRS' }
kind: 'StorageV2'
identity: {
type: 'SystemAssigned'
}
properties: {
encryption: {
keySource: 'Microsoft.Keyvault'
keyvaultproperties: {
keyname: 'myStorageKey'
keyvaulturi: keyVault.properties.vaultUri
}
}
}
}

Circular dependency in Bicep/ARM: The Storage Account needs the Key Vault to exist, but the access policy in Key Vault needs the Principal ID from the Storage Account. This requires two deployments or using RBAC on Key Vault (recommended) instead of Access Policies.


6.5 Creating Encryption Scopes​

Via CLI:

# Scope with MMK
az storage account encryption-scope create \
--account-name mystorageaccount \
--resource-group myRG \
--name FinanceScope \
--key-source Microsoft.Storage

# Scope with CMK
az storage account encryption-scope create \
--account-name mystorageaccount \
--resource-group myRG \
--name HRScope \
--key-source Microsoft.KeyVault \
--key-uri $KEY_URI

Applying scope to a container:

az storage container create \
--account-name mystorageaccount \
--name employee-data \
--default-encryption-scope HRScope \
--prevent-encryption-scope-override true

The --prevent-encryption-scope-override true parameter prevents individual blobs within the container from using a different scope than the one defined in the container.


7. Control and Security​

7.1 RBAC vs Access Policies in Key Vault​

Azure Key Vault supports two access control models:

ModelRecommended?How it works
Access PoliciesLegacyPolicies directly on Key Vault per principal
Azure RBACYes (preferred)Azure Resource Manager roles applied to Key Vault

With RBAC, assign the Key Vault Crypto Service Encryption User role to the Storage Account identity. This role grants exactly the necessary permissions (get, wrapKey, unwrapKey) without excess.

az role assignment create \
--role "Key Vault Crypto Service Encryption User" \
--assignee $PRINCIPAL_ID \
--scope $(az keyvault show --name myKeyVault --query id --output tsv)

7.2 The CMK "kill switch"​

One of the main motivators for using CMK is the ability to immediately revoke access to all data:

  • Delete the key in Key Vault
  • Revoke the Storage Account identity permissions
  • Disable the entire Key Vault

Any of these actions makes the Storage Account immediately inaccessible. This is useful in scenarios of:

  • Contract termination with customers who have data in the account
  • Security incident response
  • Regulatory compliance requiring "right to be forgotten"

Attention: Azure doesn't immediately warn about the impact. Test the revocation and restoration procedure in non-production environment before depending on it.


7.3 Key usage auditing​

With CMK, each operation that uses the key (read, write, rotation) generates a log in Azure Key Vault diagnostic logs. These logs show:

  • Which identity used the key
  • When it was used
  • From which IP
  • Whether it was successful or denied

Enable diagnostics on Key Vault:

az monitor diagnostic-settings create \
--name "kv-audit-logs" \
--resource $(az keyvault show --name myKeyVault --query id --output tsv) \
--logs '[{"category":"AuditEvent","enabled":true}]' \
--workspace <log-analytics-workspace-id>

8. Decision Making​

8.1 MMK vs CMK vs CPK​

SituationBest choiceReason
Internal data without specific regulatory requirementMMKSimple, no additional cost, guaranteed durability
HIPAA, PCI-DSS, LGPD compliance with key auditingCMKComplete auditing and lifecycle control
Need for immediate "kill switch"CMKInstant revocation via Key Vault
Different clients with cryptographic isolation in the same accountCMK + Encryption ScopesKeys per department/client
Key must never leave the client environmentCPKKey provided by request, never stored in Azure
Regulatory requirement for double encryptionInfrastructure Encryption + CMKTwo independent layers
Dedicated HSM required by regulationAzure Managed HSM + CMKHardware dedicated to the client

8.2 When to use Encryption Scopes​

ScenarioUse Encryption Scope?Reason
Multiple departments with sensitive data in the same accountYesCryptographic isolation per department
Account with data from multiple clientsYesKey per client, individual revocation
Homogeneous account with a single sensitivity levelNoUnnecessary complexity
Account with few non-sensitive containersNoDefault MMK is sufficient

8.3 System-assigned vs User-assigned Identity​

SituationRecommended identityReason
One Storage Account, one Key VaultSystem-assignedSimplicity, tied to the account lifecycle
Multiple Storage Accounts in the same Key VaultUser-assignedOne identity, one access policy
Automation with Terraform/BicepUser-assignedAvoids circular dependency in deployment
Portability between accountsUser-assignedReusable across multiple resources

9. Best Practices​

  • Enable Purge Protection on Key Vault before linking to Storage. Without this, accidental deletion of the Key Vault can make data permanently inaccessible.
  • Use User-assigned Managed Identity in automation (IaC) to avoid circular dependencies between Storage Account and Key Vault.
  • Prefer Azure RBAC over Access Policies in Key Vault for more granular and auditable management.
  • Configure automatic key rotation and set the Storage Account to use the latest version of the key.
  • Enable diagnostics on Key Vault and send to Log Analytics for complete key usage auditing.
  • Test the revocation procedure in non-production environments before implementing the "kill switch" in production.
  • Use Encryption Scopes when multiple data contexts with different regulatory requirements coexist in the same Storage Account.
  • Document the dependency between Storage Account and Key Vault. If the Key Vault is moved, deleted, or has permissions changed, the Storage Account stops working.
  • Enable Infrastructure Encryption at creation, never after.

10. Common Errors​

ErrorWhy it happensHow to avoid
Storage Account inaccessible after Key Vault access changeIdentity permissions inadvertently revokedTest permission changes in non-production environment
Cannot enable Purge Protection on Key VaultKey Vault already exists without Purge Protection and cannot be enabled retroactively in some casesCreate Key Vaults with Purge Protection from the beginning
CMK linking failure: "key not found"Key deleted or specific version expiredUse automatic rotation or validate key URI
Infrastructure Encryption not enabledForgot to check the option at creationUse Bicep/ARM templates with the configuration defined
Encryption Scope accidentally disabledBlobs become immediately inaccessibleControl RBAC for Encryption Scope operations
Circular dependency in Bicep/ARMStorage needs Key Vault; Key Vault needs Storage Principal IDUse User-assigned Identity created before both
Using CPK without client implementationCPK requires application code, not automaticOnly choose CPK if there's implementation capacity in SDK
Key Vault and Storage in different regionsAdditional latency and risk of failure in case of regional failurePlace Key Vault and Storage in the same region

11. Operation and Maintenance​

11.1 Checking encryption configuration​

Via CLI:

az storage account show \
--name mystorageaccount \
--resource-group myRG \
--query encryption

Returns the current state: keySource, keyVaultProperties, and if requireInfrastructureEncryption is active.

11.2 Manually rotating the key​

# Create new key version in Key Vault
az keyvault key create \
--vault-name myKeyVault \
--name myStorageKey \
--kty RSA \
--size 2048

# Get new version
NEW_KEY_VERSION=$(az keyvault key list-versions \
--vault-name myKeyVault \
--name myStorageKey \
--query "[-1].kid" \
--output tsv)

# Update Storage Account to use new version
az storage account update \
--name mystorageaccount \
--resource-group myRG \
--encryption-key-uri $NEW_KEY_VERSION

11.3 Monitoring Key Vault access issues​

Configure alerts in Azure Monitor for:

  • Authentication failures in Key Vault: Indicates that the Storage Account identity lost permission.
  • Key disabled or expired: Causes immediate Storage Account inaccessibility.
  • Key purge: Irreversible event.
az monitor activity-log alert create \
--name "keyvault-key-disabled" \
--resource-group myRG \
--condition category=Administrative and operationName=Microsoft.KeyVault/vaults/keys/update \
--action-group myActionGroup

11.4 Important limits​

LimitValue
Maximum Encryption Scopes per Storage Account10,000
Minimum RSA key size for CMK2048 bits
Supported key typesRSA, RSA-HSM
EC (Elliptic Curve) supported?No for Storage

12. Integration and Automation​

12.1 Azure Policy for encryption compliance​

Ensure all Storage Accounts use CMK:

# Assign built-in policy
az policy assignment create \
--name "storage-cmk-required" \
--policy "6fac406b-40ca-413b-bf8e-0bf964659c25" \
--scope "/subscriptions/<subscription-id>"

The built-in policy Storage accounts should use customer-managed key for encryption audits or denies accounts without CMK.

12.2 Rotation automation with Azure Automation​

Create a PowerShell Runbook that:

  1. Lists all Storage Accounts with CMK configured
  2. Checks the age of the current key version
  3. Creates new version if the key is older than 90 days
  4. Updates the Storage Account to the new version

12.3 Integration with Azure Defender for Storage​

Microsoft Defender for Storage monitors anomalous access patterns to the Storage Account, including attempts to access data with decryption failures, which may indicate wrong key usage or attack.

az security pricing create \
--name StorageAccounts \
--tier Standard

13. Final Summary​

Essential concepts:

  • Every Storage Account in Azure has AES-256 encryption at rest mandatory active. Cannot be disabled.
  • The difference is in who controls the KEK (Key Encryption Key): Microsoft (MMK), the customer via Key Vault (CMK), or the customer via request (CPK).
  • The two-layer model (DEK + KEK) allows rotation and access revocation without re-encrypting physical data.

Critical differences:

  • MMK: Zero operational effort, zero visibility and control over the key.
  • CMK: Complete control and comprehensive auditing, but requires Key Vault with Soft Delete and Purge Protection, Managed Identity and configured permissions.
  • CPK: Key never stored in Azure, provided by request. Requires implementation in application code.
  • Encryption Scope: Allows different keys per container or blob within the same Storage Account.
  • Infrastructure Encryption: Second layer of encryption, enabled only at creation, always managed by Microsoft.

What needs to be remembered:

  • Key Vault needs Soft Delete and Purge Protection enabled to be used with CMK.
  • The Storage Account accesses Key Vault via Managed Identity with permissions get, wrapKey, unwrapKey.
  • Revoking Key Vault access makes the Storage Account immediately inaccessible.
  • Infrastructure Encryption can only be enabled at account creation.
  • Encryption Scopes cannot be deleted, only disabled (and data becomes inaccessible while disabled).
  • Key Vault and Storage Account should be preferably in the same region to minimize latency and failure risk.