Back to Blog
3 min read

Azure Storage Account Security Best Practices

Securing Azure Storage requires multiple layers of defense. Network restrictions, encryption, access control, and monitoring—here’s the complete guide.

Network Security

Private Endpoints

# Create private endpoint
az network private-endpoint create \
    --name storage-endpoint \
    --resource-group myRG \
    --vnet-name myVNet \
    --subnet private-endpoints \
    --private-connection-resource-id $(az storage account show -n mystorageaccount -g myRG --query id -o tsv) \
    --group-id blob \
    --connection-name storage-connection

Service Endpoints

# Enable service endpoint
az network vnet subnet update \
    --resource-group myRG \
    --vnet-name myVNet \
    --name default \
    --service-endpoints Microsoft.Storage

# Restrict storage to subnet
az storage account network-rule add \
    --account-name mystorageaccount \
    --resource-group myRG \
    --vnet-name myVNet \
    --subnet default

Firewall Rules

# Deny all by default
az storage account update \
    --name mystorageaccount \
    --resource-group myRG \
    --default-action Deny

# Allow specific IPs
az storage account network-rule add \
    --account-name mystorageaccount \
    --resource-group myRG \
    --ip-address 203.0.113.0/24

Encryption

Customer-Managed Keys

# Create key in Key Vault
az keyvault key create \
    --vault-name mykeyvault \
    --name storage-key \
    --kty RSA \
    --size 2048

# Configure storage with CMK
az storage account update \
    --name mystorageaccount \
    --resource-group myRG \
    --encryption-key-vault https://mykeyvault.vault.azure.net \
    --encryption-key-name storage-key \
    --encryption-key-source Microsoft.Keyvault

Infrastructure Encryption

# Double encryption
az storage account create \
    --name mystorageaccount \
    --resource-group myRG \
    --require-infrastructure-encryption true

Access Control

Azure AD Authentication

// Use managed identity
var credential = new DefaultAzureCredential();
var blobClient = new BlobServiceClient(
    new Uri("https://mystorageaccount.blob.core.windows.net"),
    credential
);

RBAC Roles

# Assign roles
az role assignment create \
    --assignee user@company.com \
    --role "Storage Blob Data Reader" \
    --scope /subscriptions/.../storageAccounts/mystorageaccount

# Common roles:
# - Storage Blob Data Reader
# - Storage Blob Data Contributor
# - Storage Blob Data Owner
# - Storage Queue Data Contributor

Shared Access Signatures

// User delegation SAS (Azure AD backed)
var userDelegationKey = await blobServiceClient.GetUserDelegationKeyAsync(
    DateTimeOffset.UtcNow,
    DateTimeOffset.UtcNow.AddHours(1)
);

var sasBuilder = new BlobSasBuilder
{
    BlobContainerName = "container",
    Resource = "c",
    StartsOn = DateTimeOffset.UtcNow,
    ExpiresOn = DateTimeOffset.UtcNow.AddHours(1)
};
sasBuilder.SetPermissions(BlobContainerSasPermissions.Read);

var sasToken = sasBuilder.ToSasQueryParameters(userDelegationKey, accountName);

Stored Access Policies

# Create policy on container
az storage container policy create \
    --container-name mycontainer \
    --account-name mystorageaccount \
    --name read-only-policy \
    --permissions r \
    --expiry 2021-12-31

Monitoring

Diagnostic Logs

az monitor diagnostic-settings create \
    --name storage-diagnostics \
    --resource /subscriptions/.../storageAccounts/mystorageaccount/blobServices/default \
    --logs '[{
        "category": "StorageRead",
        "enabled": true
    },{
        "category": "StorageWrite",
        "enabled": true
    },{
        "category": "StorageDelete",
        "enabled": true
    }]' \
    --workspace /subscriptions/.../workspaces/security-logs

Alerts

# Alert on anonymous access
az monitor metrics alert create \
    --name anonymous-access-alert \
    --resource-group myRG \
    --scopes /subscriptions/.../storageAccounts/mystorageaccount \
    --condition "total transactions where Authentication=='Anonymous' > 0" \
    --action /subscriptions/.../actionGroups/security-team

Security Checklist

  • Disable public blob access
  • Require secure transfer (HTTPS)
  • Use private endpoints
  • Enable soft delete
  • Use Azure AD authentication
  • Rotate access keys regularly
  • Enable diagnostic logging
  • Use customer-managed keys
  • Configure firewall rules

Storage security: protect your data at every layer.

Michael John Peña

Michael John Peña

Senior Data Engineer based in Sydney. Writing about data, cloud, and technology.