Skip to content

Account Encryption

Lab Objective

In this hands-on lab, you will learn how to:

  • Configure storage account encryption with Microsoft-managed and customer-managed keys
  • Set up Azure Key Vault integration for customer-managed keys (CMK)
  • Implement encryption scopes for granular encryption control
  • Configure encryption at rest and in transit for comprehensive data protection
  • Test key rotation scenarios and disaster recovery procedures
  • Monitor encryption status and compliance requirements
  • Troubleshoot encryption-related access issues

Scenario: Your organization has strict data protection requirements that mandate customer-managed encryption keys for sensitive data. You’ll configure various encryption options and test key management scenarios to ensure compliance and security.


Pre-Provisioned Environment

The following Azure resources have been pre-deployed in your environment:

Resource Overview

Resource TypeResource NameConfigurationPurpose
Resource GroupEncryption-Lab-RGContains all lab resourcesLogical container
Key Vaultencryptionkv[unique]East US, RBAC enabledCustomer-managed keys
Storage Accountmskmanagedstore[unique]Microsoft-managed keysDefault encryption
Storage Accountcmkstore[unique]Ready for CMK setupCustomer-managed encryption
Storage Accountscopestore[unique]Multiple encryption scopesScope-based encryption
User IdentityEncryptionIdentityManaged identityKey Vault access
Test VMEncryptionVMWindows Server 2019Encryption testing

Key Vault Configuration

ComponentConfigurationPurpose
Access Policy ModelRBAC (Recommended)Modern permission model
Soft DeleteEnabled (90 days)Key recovery protection
Purge ProtectionEnabledPermanent deletion prevention
Network AccessAll networks (for lab)Connectivity testing

Storage Account Encryption Status

AccountEncryption TypeKey SourceEncryption Scope
mskmanagedstore[unique]Microsoft-managedMicrosoft.StorageDefault
cmkstore[unique]Ready for CMKWill configureCustom
scopestore[unique]Multiple scopesMixedMultiple

Managed Identity Details

IdentityTypePermissionsPurpose
EncryptionIdentityUser-assignedKey Vault accessCMK operations

Lab Exercises

Part 1: Understand Default Encryption

Step 1: Examine Microsoft-Managed Encryption

  1. Navigate to Encryption-Lab-RG resource group
  2. Click on mskmanagedstore[unique] storage account
  3. Go to Security + NetworkingEncryption

Observe the default settings:

  • Encryption type: Microsoft-managed keys
  • Infrastructure encryption: Disabled (can be enabled for additional security)
  • Blob service: Enabled
  • File service: Enabled
  • Table service: Enabled
  • Queue service: Enabled

Step 2: Upload Test Data

  1. Go to Storage browserBlob containers
  2. Create a new container named test-data
  3. Set access level to Private
  4. Upload sample files:
    • Create a text file with sample sensitive data
    • Upload an image or document
    • Note: All data is automatically encrypted at rest

Step 3: Understand Encryption Scope

Key Point: With Microsoft-managed keys:

  • Azure handles all encryption key management
  • No additional configuration required
  • Keys are rotated automatically by Microsoft
  • No additional cost for encryption

Part 2: Configure Customer-Managed Keys (CMK)

Step 1: Create Encryption Key in Key Vault

  1. Navigate to encryptionkv[unique] Key Vault
  2. Go to ObjectsKeys
  3. Click “Generate/Import”

Create new key:

  • Name: StoragePrimaryKey
  • Key type: RSA
  • RSA key size: 2048
  • Set activation/expiration dates: (Optional)
  • Click Create

Step 2: Configure Storage Account Identity

  1. Navigate to cmkstore[unique] storage account
  2. Go to Security + NetworkingIdentity
  3. System assigned identity:
    • Status: On
    • Click Save
  4. Note the Object (principal) ID for later use

Step 3: Grant Key Vault Permissions

  1. Return to encryptionkv[unique] Key Vault
  2. Go to Access control (IAM)
  3. Click “Add role assignment”

Assign role:

  • Role: Key Vault Crypto Service Encryption User
  • Assign access to: Managed identity
  • Members: Select the storage account identity
  • Click Review + assign

Step 4: Configure Customer-Managed Key

  1. Return to cmkstore[unique] storage account
  2. Go to Security + NetworkingEncryption
  3. Change encryption type:
    • Select Customer-managed keys
    • Key selection method: Select from Key Vault
    • Key Vault: encryptionkv[unique]
    • Key: StoragePrimaryKey
    • Version: (Latest) or specific version
  4. Click Save

Step 5: Test CMK Encryption

  1. Create a new container named cmk-test-data
  2. Upload test files
  3. Verify encryption status:
    • Go back to Encryption settings
    • Confirm it shows “Customer-managed keys”
    • Note the key version in use

Part 3: Understanding Encryption Scopes

Step 1: Create Encryption Scopes (Portal Method)

  1. Navigate to scopestore[unique] storage account
  2. Go to Security + NetworkingEncryption
  3. Scroll down to Encryption scopes
  4. Click “Add encryption scope”

Create Default Scope:

  • Name: DefaultScope
  • Encryption type: Microsoft-managed keys
  • Infrastructure encryption: Disabled
  • Click Add

Create Sensitive Scope:

  • Name: SensitiveScope
  • Encryption type: Customer-managed keys
  • Key Vault: encryptionkv[unique]
  • Key: StoragePrimaryKey
  • Click Add

Step 2: Test Scope-Based Uploads

  1. Go to Storage browserBlob containers
  2. Create containers:
    • general-data (for default scope)
    • sensitive-data (for sensitive scope)

Upload with specific scopes:

  1. In Azure Storage Explorer or portal:
    • When uploading to general-data, use DefaultScope
    • When uploading to sensitive-data, use SensitiveScope
  2. Verify scope assignment in blob properties

Step 3: Compare Encryption Methods

Create a comparison table:

ContainerEncryption MethodKey ManagementUse Case
test-dataMicrosoft-managedAutomaticGeneral data
cmk-test-dataCustomer-managedManual rotationSensitive data
general-dataScope: DefaultAutomaticStandard files
sensitive-dataScope: CustomerManual rotationConfidential files

Part 4: Key Rotation and Management

Step 1: Create New Key Version (Portal)

  1. Navigate to encryptionkv[unique] Key Vault
  2. Go to ObjectsKeysStoragePrimaryKey
  3. Click “New Version”
  4. Keep same settings, click Create
  5. Note the new version number

Step 2: Update Storage Account Key Version

  1. Navigate to cmkstore[unique] storage account
  2. Go to Security + NetworkingEncryption
  3. Update key version:
    • Change from “Latest” to the new specific version
    • OR keep as “Latest” for automatic updates
  4. Click Save

Step 3: Test Data Access After Rotation

  1. Access existing data in the CMK container
  2. Upload new data to verify encryption works
  3. Confirm both old and new data remain accessible

Key Learning Points:

  • Existing data remains accessible with old key versions
  • New data uses the current key version
  • Azure maintains access to all key versions needed

Part 5: Monitor Encryption Status

Step 1: Create Encryption Monitoring Checklist

Review each storage account:

Storage AccountEncryption TypeKey SourceStatus
mskmanagedstore[unique]Microsoft-managedMicrosoft.Storage✅ Active
cmkstore[unique]Customer-managedKey Vault✅ Active
scopestore[unique]Multiple scopesMixed✅ Active

Step 2: Verify Compliance Requirements

Check each requirement:

  • ✅ All data encrypted at rest
  • ✅ Customer-managed keys for sensitive data
  • ✅ Key rotation capability demonstrated
  • ✅ Access controls properly configured
  • ✅ Encryption scopes properly applied

Step 3: Document Key Management Procedures

Create procedures for:

  1. Regular key rotation (quarterly/annually)
  2. Key backup and recovery processes
  3. Access review for Key Vault permissions
  4. Monitoring encryption status changes
  5. Incident response for key compromise

Optional Advanced Exercises

For users wanting more technical depth, try these PowerShell-based exercises:

Advanced Exercise 1: Automated Key Rotation

Terminal window
# Connect to Azure (run in CloudShell or local PowerShell)
Connect-AzAccount
# Create new key version and update storage automatically
$keyVault = "encryptionkv[unique]"
$storageAccount = "cmkstore[unique]"
$resourceGroup = "Encryption-Lab-RG"
# Create new key version
$newKey = Add-AzKeyVaultKey -VaultName $keyVault -Name "StoragePrimaryKey" -Destination "Software"
# Update storage account to use new version
Set-AzStorageAccount -ResourceGroupName $resourceGroup -Name $storageAccount -KeyvaultEncryption -KeyName "StoragePrimaryKey" -KeyVersion $newKey.Version -KeyVaultUri "https://$keyVault.vault.azure.net/"

Advanced Exercise 2: Bulk Encryption Status Check

Terminal window
# Check encryption status across all storage accounts
Get-AzStorageAccount -ResourceGroupName "Encryption-Lab-RG" | ForEach-Object {
Write-Host "Account: $($_.StorageAccountName)"
Write-Host " Encryption: $($_.Encryption.KeySource)"
if ($_.Encryption.KeyVaultProperties) {
Write-Host " Key: $($_.Encryption.KeyVaultProperties.KeyName)"
}
Write-Host "---"
}

Optional Advanced Exercises

For users wanting more technical depth, try these PowerShell-based exercises:

Step 2: Test Key Rotation Impact

Terminal window
# Update storage account to use new key version
Write-Host "Updating storage account to use new key version..."
Set-AzStorageAccount -ResourceGroupName $resourceGroup -Name $cmkAccount -KeyvaultEncryption -KeyName "StoragePrimaryKey" -KeyVersion $newPrimaryKey.Version -KeyVaultUri $keyVaultUri
# Verify the update
$updatedCmkStorage = Get-AzStorageAccount -ResourceGroupName $resourceGroup -Name $cmkAccount
Write-Host "Updated CMK configuration:"
Write-Host " Key Version (Old): $($primaryKey.Version)"
Write-Host " Key Version (New): $($updatedCmkStorage.Encryption.KeyVaultProperties.KeyVersion)"
# Test access to existing encrypted data
Write-Host "Testing access to existing encrypted data after key rotation..."
$cmkContext = $updatedCmkStorage.Context
try {
$blobs = Get-AzStorageBlob -Container "cmk-encrypted-data" -Context $cmkContext
Write-Host "SUCCESS: Can access existing encrypted blobs after key rotation"
Write-Host " Accessible blobs: $($blobs.Count)"
} catch {
Write-Host "ERROR: Cannot access existing encrypted blobs after key rotation"
Write-Host " Error: $($_.Exception.Message)"
}
# Upload new data with rotated key
$newTestFile = "C:\temp\rotated-key-test.txt"
New-Item -ItemType Directory -Path "C:\temp" -Force
"Test data encrypted with rotated key - $(Get-Date)" | Out-File -FilePath $newTestFile -Encoding UTF8
Set-AzStorageBlobContent -File $newTestFile -Container "cmk-encrypted-data" -Blob "rotated-key-test.txt" -Context $cmkContext -Force
Write-Host "SUCCESS: Uploaded new data with rotated key"

Step 3: Test Key Disabling Scenario

Terminal window
# Simulate key compromise scenario by disabling the old key version
Write-Host "Testing key disabling scenario..."
# First, ensure we're using the new key version
$currentStorage = Get-AzStorageAccount -ResourceGroupName $resourceGroup -Name $cmkAccount
Write-Host "Current key version in use: $($currentStorage.Encryption.KeyVaultProperties.KeyVersion)"
# Disable the old key version (simulate key compromise)
Update-AzKeyVaultKey -VaultName $keyVaultName -Name "StoragePrimaryKey" -Version $primaryKey.Version -Enable $false
Write-Host "Disabled old key version: $($primaryKey.Version)"
# Test access with disabled key
Start-Sleep -Seconds 10 # Wait for changes to propagate
try {
$testAccess = Get-AzStorageBlob -Container "cmk-encrypted-data" -Context $cmkContext | Select-Object -First 1
Write-Host "Storage access status: ACCESSIBLE (using current key version)"
} catch {
Write-Host "Storage access status: FAILED - $($_.Exception.Message)"
}
# Re-enable the key for continued testing
Update-AzKeyVaultKey -VaultName $keyVaultName -Name "StoragePrimaryKey" -Version $primaryKey.Version -Enable $true
Write-Host "Re-enabled old key version for testing continuity"

Part 5: Monitor Encryption Status and Compliance

Step 1: Create Encryption Monitoring Dashboard

Terminal window
# Function to check encryption status across all storage accounts
function Get-EncryptionStatus {
$allAccounts = @($mskAccount, $cmkAccount, $scopeAccount)
Write-Host "=== ENCRYPTION STATUS REPORT ==="
Write-Host "Generated: $(Get-Date)"
Write-Host ""
foreach ($accountName in $allAccounts) {
$account = Get-AzStorageAccount -ResourceGroupName $resourceGroup -Name $accountName
Write-Host "Storage Account: $accountName"
Write-Host " Encryption Source: $($account.Encryption.KeySource)"
if ($account.Encryption.KeySource -eq "Microsoft.Keyvault") {
Write-Host " Key Vault: $($account.Encryption.KeyVaultProperties.KeyVaultUri)"
Write-Host " Key Name: $($account.Encryption.KeyVaultProperties.KeyName)"
Write-Host " Key Version: $($account.Encryption.KeyVaultProperties.KeyVersion)"
}
Write-Host " Service Encryption Status:"
Write-Host " Blob: $($account.Encryption.Services.Blob.Enabled)"
Write-Host " File: $($account.Encryption.Services.File.Enabled)"
Write-Host " Table: $($account.Encryption.Services.Table.Enabled)"
Write-Host " Queue: $($account.Encryption.Services.Queue.Enabled)"
# Check for encryption scopes
try {
$scopes = Get-AzStorageEncryptionScope -ResourceGroupName $resourceGroup -StorageAccountName $accountName
if ($scopes) {
Write-Host " Encryption Scopes: $($scopes.Count)"
$scopes | ForEach-Object {
Write-Host " - $($_.Name): $($_.Source)"
}
}
} catch {
Write-Host " Encryption Scopes: None or not accessible"
}
Write-Host "---"
}
}
Get-EncryptionStatus

Step 2: Audit Key Usage and Access

Terminal window
# Check Key Vault access logs (requires diagnostic settings in production)
Write-Host "Key Vault Audit Information:"
Write-Host "Key Vault: $keyVaultName"
# List all keys and their versions
$allKeys = Get-AzKeyVaultKey -VaultName $keyVaultName
$allKeys | ForEach-Object {
Write-Host "Key: $($_.Name)"
# Get all versions
$versions = Get-AzKeyVaultKey -VaultName $keyVaultName -Name $_.Name -IncludeVersions
Write-Host " Total Versions: $($versions.Count)"
$versions | ForEach-Object {
$status = if ($_.Enabled) { "Active" } else { "Disabled" }
Write-Host " Version: $($_.Version) - Created: $($_.Created) - Status: $status"
}
Write-Host "---"
}
# Check storage accounts using each key
Write-Host "Key Usage Analysis:"
$storageAccounts = Get-AzStorageAccount -ResourceGroupName $resourceGroup
$storageAccounts | Where-Object { $_.Encryption.KeySource -eq "Microsoft.Keyvault" } | ForEach-Object {
Write-Host "Storage Account: $($_.StorageAccountName)"
Write-Host " Uses Key: $($_.Encryption.KeyVaultProperties.KeyName)"
Write-Host " Key Version: $($_.Encryption.KeyVaultProperties.KeyVersion)"
}

Step 3: Test Compliance Scenarios

Terminal window
# Simulate compliance audit scenarios
Write-Host "=== COMPLIANCE AUDIT SCENARIOS ==="
# Scenario 1: Verify all sensitive data uses CMK
Write-Host "1. Checking sensitive data encryption compliance..."
$scopeContext = (Get-AzStorageAccount -ResourceGroupName $resourceGroup -Name $scopeAccount).Context
$sensitiveBlobs = Get-AzStorageBlob -Container "sensitive-encrypted" -Context $scopeContext
$sensitiveBlobs | ForEach-Object {
$encryptionScope = $_.BlobProperties.EncryptionScope
if ($encryptionScope -eq "SensitiveScope") {
Write-Host " ✓ COMPLIANT: $($_.Name) - Encrypted with customer-managed key"
} else {
Write-Host " ✗ NON-COMPLIANT: $($_.Name) - Using incorrect encryption scope: $encryptionScope"
}
}
# Scenario 2: Verify key rotation recency
Write-Host "2. Checking key rotation compliance (keys should be less than 90 days old)..."
$keyAge = (Get-Date) - $newPrimaryKey.Created
if ($keyAge.Days -le 90) {
Write-Host " ✓ COMPLIANT: Key rotated $($keyAge.Days) days ago"
} else {
Write-Host " ✗ NON-COMPLIANT: Key is $($keyAge.Days) days old, exceeds 90-day policy"
}
# Scenario 3: Verify key access restrictions
Write-Host "3. Checking key access permissions..."
$keyVaultDetails = Get-AzKeyVault -VaultName $keyVaultName -ResourceGroupName $resourceGroup
Write-Host " Key Vault Access Model: $($keyVaultDetails.EnableRbacAuthorization)"
Write-Host " Soft Delete: $($keyVaultDetails.EnableSoftDelete)"
Write-Host " Purge Protection: $($keyVaultDetails.EnablePurgeProtection)"
if ($keyVaultDetails.EnableSoftDelete -and $keyVaultDetails.EnablePurgeProtection) {
Write-Host " ✓ COMPLIANT: Key protection features enabled"
} else {
Write-Host " ✗ NON-COMPLIANT: Missing key protection features"
}

Part 6: Disaster Recovery and Key Management

Step 1: Create Key Backup Strategy

Terminal window
# Create backup of encryption keys
Write-Host "Creating key backup strategy..."
$backupPath = "C:\KeyBackups"
New-Item -ItemType Directory -Path $backupPath -Force
# Backup all encryption keys
$allKeys = Get-AzKeyVaultKey -VaultName $keyVaultName
$allKeys | ForEach-Object {
$keyName = $_.Name
$backupFile = "$backupPath\$keyName-backup.blob"
try {
$backup = Backup-AzKeyVaultKey -VaultName $keyVaultName -Name $keyName -OutputFile $backupFile -Force
Write-Host "✓ Backed up key: $keyName to $backupFile"
} catch {
Write-Host "✗ Failed to backup key: $keyName - $($_.Exception.Message)"
}
}
Write-Host "Key backup completed. Files stored in: $backupPath"
Get-ChildItem $backupPath | Select-Object Name, Length, LastWriteTime

Step 2: Test Key Recovery Scenario

Terminal window
# Simulate key recovery scenario
Write-Host "Testing key recovery scenario..."
# Create a test key for recovery simulation
$testKey = Add-AzKeyVaultKey -VaultName $keyVaultName -Name "TestRecoveryKey" -Destination "Software" -KeyType "RSA" -Size 2048
Write-Host "Created test key: $($testKey.Name)"
# Backup the test key
$testBackupFile = "$backupPath\TestRecoveryKey-backup.blob"
Backup-AzKeyVaultKey -VaultName $keyVaultName -Name "TestRecoveryKey" -OutputFile $testBackupFile -Force
Write-Host "Backed up test key"
# Delete the test key (simulate disaster)
Remove-AzKeyVaultKey -VaultName $keyVaultName -Name "TestRecoveryKey" -Force -Confirm:$false
Write-Host "Deleted test key (simulating disaster)"
# Verify key is gone
try {
Get-AzKeyVaultKey -VaultName $keyVaultName -Name "TestRecoveryKey"
Write-Host "Key still exists (unexpected)"
} catch {
Write-Host "✓ Confirmed: Key is deleted"
}
# Restore the key from backup
try {
$restoredKey = Restore-AzKeyVaultKey -VaultName $keyVaultName -InputFile $testBackupFile
Write-Host "✓ Successfully restored key: $($restoredKey.Name)"
Write-Host " Restored Version: $($restoredKey.Version)"
} catch {
Write-Host "✗ Failed to restore key: $($_.Exception.Message)"
}
# Clean up test key
Remove-AzKeyVaultKey -VaultName $keyVaultName -Name "TestRecoveryKey" -Force -Confirm:$false
Write-Host "Cleaned up test key"

Step 3: Document Recovery Procedures

Terminal window
# Generate disaster recovery documentation
$drDocument = @"
=== ENCRYPTION KEY DISASTER RECOVERY PROCEDURES ===
Generated: $(Get-Date)
Key Vault: $keyVaultName
Resource Group: $resourceGroup
BACKUP LOCATIONS:
- Key Vault Backups: $backupPath
- Keys backed up: $($allKeys.Count)
RECOVERY STEPS:
1. Ensure Key Vault is accessible and operational
2. Restore keys from backup files using:
Restore-AzKeyVaultKey -VaultName $keyVaultName -InputFile <backup-file>
3. Update storage accounts to use restored keys
4. Verify encryption/decryption functionality
5. Test data access across all storage accounts
STORAGE ACCOUNTS AFFECTED:
- $cmkAccount (Customer-managed keys)
- $scopeAccount (Multiple encryption scopes)
EMERGENCY CONTACTS:
- Azure Support: [Your support plan details]
- Key Vault Administrator: [Admin contact]
- Security Team: [Security team contact]
TESTING REQUIREMENTS:
- Test key recovery monthly
- Verify storage account access after recovery
- Document any access issues or delays
"@
$drDocument | Out-File -FilePath "$backupPath\DisasterRecoveryProcedures.txt" -Encoding UTF8
Write-Host "Disaster recovery documentation created: $backupPath\DisasterRecoveryProcedures.txt"

Troubleshooting Guide

Common Encryption Issues

IssueSymptomsPossible CauseSolution
CMK setup failsConfiguration errorsMissing permissionsVerify managed identity has Key Vault access
Data access denied403 errors accessing blobsKey disabled or deletedCheck key status in Key Vault
Encryption scope errorsCannot upload with scopeScope not configured properlyVerify scope exists and key is accessible
Key rotation failsStorage account not updatedNetwork or permission issuesCheck Key Vault connectivity and permissions
Backup restore failsKey restoration errorsCorrupted backup or permissionsVerify backup file integrity and permissions

Encryption Configuration Checklist

ComponentRequirementStatusNotes
Key VaultSoft delete enabledRequired for production
Key VaultPurge protection enabledPrevents permanent key deletion
Managed IdentityKey Vault permissionsCrypto Officer or custom permissions
Storage AccountIdentity assignedSystem or user-assigned
KeysRSA 2048+ or HSMMinimum key strength
BackupRegular key backupsMonthly backup recommended

Performance Considerations

ScenarioImpactMitigation
CMK vs MSKSlightly higher latencyUse for sensitive data only
Key rotationTemporary access delaysPerform during maintenance windows
Cross-region keysNetwork latencyUse regional Key Vaults
Multiple scopesManagement complexityDocument scope usage policies
HSM keysHigher costsUse only for highest sensitivity data

Additional Experiments

Try these optional exercises to deepen your understanding:

  • HSM-Protected Keys: Configure HSM-protected keys for highest security
  • Cross-Tenant Scenarios: Set up encryption across different Azure tenants
  • Automated Key Rotation: Implement automated key rotation using Azure Functions
  • Compliance Reporting: Create automated compliance reports for encryption status
  • Multi-Region DR: Test disaster recovery across multiple Azure regions

Key Takeaways

After completing this lab, you should understand:

  • Default encryption uses Microsoft-managed keys with no additional configuration
  • Customer-managed keys provide additional control but require Key Vault setup
  • Encryption scopes enable granular encryption policies within storage accounts
  • Managed identities are essential for secure Key Vault integration
  • Key rotation is crucial for security but requires careful planning
  • Backup and recovery procedures are critical for business continuity
  • Compliance monitoring requires regular auditing of encryption configurations

Encryption Decision Matrix

When to Use Each Encryption Type

Data TypeRecommended EncryptionJustification
Public dataMicrosoft-managedCost-effective, adequate protection
Internal documentsMicrosoft-managed or Default scopeStandard protection, low management overhead
Sensitive customer dataCustomer-managed keysFull control, compliance requirements
Financial recordsCMK with HSMHighest security, regulatory compliance
Archive dataSeparate encryption scopeCost optimization, long-term management
Development/testMicrosoft-managedSimple setup, non-production data

Cost Considerations

Encryption TypeAdditional CostsManagement Overhead
Microsoft-managedNoneMinimal
Customer-managedKey Vault operationsMedium
Multiple scopesKey Vault + managementHigh
HSM-protectedHSM usage feesHigh
Cross-regionData transfer costsMedium

Additional Resources