Theoretical Foundation: Configure Soft Delete for Blobs and Containers
1. Initial Intuitionβ
Imagine you work with an operating system that has a recycle bin. When you delete a file, it doesn't disappear immediately: it goes to the recycle bin and remains there for a period. If you change your mind, you can restore it. Only after emptying the recycle bin (or after the automatic deadline) is the file permanently removed.
Soft Delete in Azure Blob Storage is exactly that recycle bin, applied to blobs and containers. When enabled, any deletion is temporary: the data goes into a "soft-deleted" state for a configurable period, during which it can be restored with a single operation. After this period, it is permanently removed.
This protects against two of the most common and devastating errors in cloud environments: accidental deletion by an operator and malicious deletion by ransomware or an attacker who compromised credentials.
2. Contextβ
2.1 Soft Delete within the data protection strategyβ
Azure offers multiple layers of protection for data in Blob Storage. Soft Delete is one of them:
Soft Delete is the simplest and lowest-cost layer to implement. It's the minimum recommended by Microsoft for any production Storage Account.
2.2 What Soft Delete protects and what it doesn't protectβ
| Protects against | Doesn't protect against |
|---|---|
| Accidental deletion of blobs | Corruption of blob content (file overwritten with bad data) |
| Accidental deletion of containers | Deletion after retention period expires |
| Ransomware attacks that delete blobs | Ransomware that overwrites blob content |
| Buggy scripts that delete data | Intentional deletion within the period (admins with permission) |
For protection against content overwriting, combine Soft Delete with Blob Versioning.
3. Building the Conceptsβ
3.1 Blob soft delete vs Container soft deleteβ
There are two independent mechanisms of Soft Delete in Azure Blob Storage:
Blob Soft Delete:
- Applied to individual blobs
- When a blob is deleted, it enters the soft-deleted state
- Available for restoration for the configured period
- Configured in days (1 to 365)
- Works for Block Blobs, Append Blobs, and Page Blobs
Container Soft Delete:
- Applied to entire containers
- When a container is deleted (with all its content), the container enters the soft-deleted state
- All container content is recoverable
- Configured in days (1 to 365)
- Configured separately from blob soft delete
Critical point: The two mechanisms are independent. You can enable one without the other. If a blob within a container is deleted, blob soft delete applies (not container). If the entire container is deleted, container soft delete applies.
3.2 States of a blob with Soft Delete enabledβ
3.3 States of a container with Soft Delete enabledβ
3.4 Interaction between Blob Soft Delete and Blob Versioningβ
When Blob Versioning is enabled alongside Soft Delete, the behavior changes:
- Each modification of a blob creates a new version
- When the current blob is deleted, the current version becomes a previous version (doesn't enter soft-delete because versioning preserves it automatically)
- Soft Delete now protects previous versions that are explicitly deleted
In practice, with Versioning enabled, blob soft delete protects deleted versions, not the "current" blob (which when deleted simply becomes a previous version).
This interaction is one of the most complex points covered in the AZ-104.
3.5 Soft Delete and snapshotsβ
Blob snapshots also interact with Soft Delete:
- If you delete a blob with its snapshots, and Soft Delete is active, both the blob and snapshots enter the soft-deleted state.
- If you delete only a specific snapshot, it enters soft-deleted.
- Blob restoration via
Undeleterestores the blob and all its soft-deleted snapshots simultaneously.
3.6 The cost of Soft Deleteβ
Soft-deleted data still occupies space and is still billed, in the blob's access tier at the time of deletion:
- A 10 GB blob in Hot tier deleted on day 1 continues to be billed for 10 GB in Hot during the entire retention period.
- If the blob was recently moved to Archive and then deleted, the retention cost is in the Archive tier.
This is important for sizing the retention period: long periods on high-volume data can have significant cost impact.
4. Structural Viewβ
5. How It Works in Practiceβ
5.1 What happens internally when deleting a blobβ
When Soft Delete is enabled and you execute a Delete Blob operation:
- Azure doesn't physically remove the data. It marks the blob with the property
Deleted: trueand records the expiration date (current date + retention period). - The blob disappears from standard listings (
List Blobswithout the include deleted parameter). - The blob continues to occupy space and be billed.
- Any attempt to access the blob via URL returns
404 Not Found(as if it doesn't exist). - To see soft-deleted blobs, you need to use
List Blobswith theinclude=deletedparameter. - To restore, you execute
Undelete Blob.
5.2 What happens when deleting a containerβ
When Container Soft Delete is enabled and you execute Delete Container:
- The container and all its blobs enter the soft-deleted state simultaneously.
- The container no longer appears in normal container listings.
- To list soft-deleted containers, use
List Containerswithinclude=deleted. - To restore, execute
Restore Container, which recreates the container with the same name and restores all blobs that were in it.
Non-obvious behavior: If you try to create a new container with the same name as a soft-deleted container, the operation fails while the soft-deleted container exists. Azure reserves the name during the retention period.
5.3 Restoring a soft-deleted blobβ
The Undelete Blob operation (or Restore Blob in some interfaces) restores the blob to the active state. The operation:
- Doesn't require special parameters beyond blob identification
- Restores the blob to the same container where it was
- Also restores all soft-deleted snapshots of the blob
- Doesn't change the blob's tier (keeps the tier it had before deletion)
6. Implementation Methodsβ
6.1 Azure Portalβ
Enabling Blob Soft Delete:
Storage Account > Data Protection > Enable soft delete for blobs
You define the retention period in days (1 to 365). The portal shows a visual slider.
Enabling Container Soft Delete:
Storage Account > Data Protection > Enable soft delete for containers
Period configured separately, also from 1 to 365 days.
Restoring deleted blobs in the portal:
Storage Account > Containers > [container] > Show deleted blobs
The portal displays soft-deleted blobs with a distinct icon and allows individual restoration by clicking on the blob and selecting "Undelete".
Restoring deleted container in the portal:
Storage Account > Containers > (select "Show deleted containers" at the top of the listing)
Soft-deleted containers appear in the list with "Deleted" status. Select and click "Restore".
6.2 Azure CLIβ
Enabling Blob and Container Soft Delete:
# Enable Blob Soft Delete with 7 days retention
az storage account blob-service-properties update \
--account-name myaccount \
--resource-group myRG \
--enable-delete-retention true \
--delete-retention-days 7
# Enable Container Soft Delete with 30 days retention
az storage account blob-service-properties update \
--account-name myaccount \
--resource-group myRG \
--enable-container-delete-retention true \
--container-delete-retention-days 30
Checking current configuration:
az storage account blob-service-properties show \
--account-name myaccount \
--resource-group myRG \
--query "{blobSoftDelete: deleteRetentionPolicy, containerSoftDelete: containerDeleteRetentionPolicy}"
Listing soft-deleted blobs:
az storage blob list \
--account-name myaccount \
--container-name mycontainer \
--include d \
--auth-mode login \
--output table
The --include d parameter instructs to list blobs in deleted state.
Restoring a soft-deleted blob:
az storage blob undelete \
--account-name myaccount \
--container-name mycontainer \
--name relatorio-deletado.xlsx \
--auth-mode login
Listing soft-deleted containers:
az storage container list \
--account-name myaccount \
--include-deleted \
--auth-mode login \
--output table
Restoring a soft-deleted container:
az storage container restore \
--account-name myaccount \
--deleted-container-name mycontainer \
--deleted-container-version <version-id> \
--auth-mode login
The --deleted-container-version is obtained from the deleted containers listing and is an internal identifier generated at the time of deletion.
6.3 Azure PowerShellβ
$ctx = New-AzStorageContext `
-StorageAccountName "myaccount" `
-UseConnectedAccount
# List soft-deleted blobs
Get-AzStorageBlob `
-Container "mycontainer" `
-Context $ctx `
-IncludeDeleted
# Restore soft-deleted blob
$blob = Get-AzStorageBlob `
-Container "mycontainer" `
-Blob "relatorio-deletado.xlsx" `
-Context $ctx `
-IncludeDeleted
$blob.ICloudBlob.UndeleteAsync()
# List soft-deleted containers
Get-AzStorageContainer `
-Context $ctx `
-IncludeDeleted
# Restore container
Restore-AzStorageContainer `
-Name "mycontainer" `
-VersionId "<version-id>" `
-Context $ctx
6.4 Bicepβ
resource blobServiceProperties 'Microsoft.Storage/storageAccounts/blobServices@2023-01-01' = {
name: '${storageAccount.name}/default'
properties: {
// Blob Soft Delete: 7 days
deleteRetentionPolicy: {
enabled: true
days: 7
}
// Container Soft Delete: 30 days
containerDeleteRetentionPolicy: {
enabled: true
days: 30
}
// Optional: enable alongside versioning
isVersioningEnabled: true
}
}
6.5 Azure Policy for complianceβ
To ensure every Storage Account has Soft Delete enabled:
# Assign built-in audit policy
az policy assignment create \
--name "require-blob-soft-delete" \
--policy "b38aa5b8-ac51-4f91-8a3e-a7ec3f58c62a" \
--scope "/subscriptions/<sub-id>"
Relevant built-in policies:
- "Blob soft delete should be enabled" (audit)
- "Configure blob soft delete for storage accounts" (automatic deploy via DeployIfNotExists)
7. Control and Securityβ
7.1 Who can perform Undeleteβ
The restoration operation (Undelete Blob, Restore Container) requires:
| Authentication method | Minimum permission |
|---|---|
| Azure AD (RBAC) | Storage Blob Data Contributor |
| Storage Account Key | Full access |
| SAS token | Permission d (delete) on blob or container |
Non-obvious point: The permission required to restore a blob is the same required to delete. This makes sense: Undelete is the inverse of Delete, and both are mutation operations on the blob's state.
7.2 Soft Delete is not protection against everythingβ
A user or script with Storage Blob Data Contributor permission can:
- Delete a blob (it goes to soft-deleted)
- List soft-deleted blobs
- Permanently delete soft-deleted blobs using the purge API
The Purge Deleted Blob operation (purge via REST API or SDK) permanently removes a soft-deleted blob before the retention period expires. To prevent this attack vector, combine Soft Delete with Immutability Policies or restrict who has
deletepermission.
For protection against ransomware that attacks with compromised credentials, Immutability Policies (WORM) are the most robust solution, as not even the administrator can delete immutable data before the deadline.
7.3 Auditing delete and restore operationsβ
Configure diagnostics to log deletion and restoration operations:
az monitor diagnostic-settings create \
--name "storage-audit" \
--resource <storage-account-id> \
--logs '[
{"category": "StorageDelete", "enabled": true},
{"category": "StorageWrite", "enabled": true}
]' \
--workspace <log-analytics-workspace-id>
With this, every Delete Blob, Undelete Blob, Delete Container, and Restore Container operation is logged with executor identity, timestamp, and result.
8. Decision Makingβ
8.1 Retention period: how long to configureβ
| Situation | Recommended period | Reason |
|---|---|---|
| Development Storage Account | 7 days | Low cost, basic protection |
| Production application with mutable data | 14 to 30 days | Adequate window to detect accidental deletions |
| Data with regulatory requirement | 30 to 365 days | Compliance requires longer window |
| Business-critical data | 30 days (blob) + 30 days (container) | Double protection |
| Account with large volume (TB) in Hot | 7 days | Retention cost vs security |
8.2 Blob soft delete vs Container soft delete: when one is not enoughβ
| Situation | Required Configuration |
|---|---|
| Protection against individual file deletion | Blob Soft Delete |
| Protection against entire container deletion | Container Soft Delete |
| Complete protection | Both enabled |
| Protection against content overwrite | Blob Versioning (Soft Delete doesn't help here) |
| Maximum ransomware protection | Immutability Policy + Soft Delete |
8.3 Soft Delete vs Blob Versioning: differencesβ
| Aspect | Soft Delete | Blob Versioning |
|---|---|---|
| Protects against | Blob deletion | Overwrite and deletion |
| When activated | On deletion | On each modification |
| Protection period | Configurable (days) | While versions exist |
| Cost | Deleted blob continues to be charged | Each version is charged separately |
| Restoration | Undelete (one operation) | Copy previous version over current |
| Recommendation | Always enable | Enable when modification history is important |
9. Best Practicesβ
- Enable Soft Delete on every production Storage Account as default policy. The cost of temporary storage during retention is much lower than the cost of an irreversible accidental deletion.
- Configure Container Soft Delete with a longer period than Blob Soft Delete. Accidental deletion of an entire container is more catastrophic and harder to detect quickly.
- Combine Soft Delete with Blob Versioning for complete protection: Versioning protects against overwrite, Soft Delete protects against deletion.
- Use Azure Policy with DeployIfNotExists effect to ensure new Storage Accounts are automatically created with Soft Delete enabled.
- Monitor
BlobCapacityof soft-deleted blobs separately to understand the real cost of the functionality. Use theBlobTypedimension with valueSoftDeletedBlob. - Document the restoration process for the operations team. During incident moments, having a clear runbook accelerates recovery.
- Configure alerts for when the volume of soft-deleted blobs increases abruptly, which may indicate an attack or script with bugs.
- Test restoration periodically in non-production environment to ensure the process works correctly before a real incident.
10. Common Errorsβ
| Error | Why it happens | How to avoid |
|---|---|---|
| Soft Delete enabled but blob is not recoverable | Retention period already expired | Monitor soft-deleted blobs and act within deadline |
| Cannot create container with same name | Soft-deleted container still exists with that name | List deleted containers and restore or wait for expiration |
| Unexpected cost after enabling Soft Delete | Deleted blobs continue being charged during retention | Size retention period considering volume of deleted data |
| Confusing Blob Soft Delete with Container | They are independent mechanisms configured separately | Check both configurations in Data Protection |
| Soft Delete doesn't protect against overwrite | Protection is only for deletion, not for content modification | Combine with Blob Versioning for complete protection |
| Soft-deleted blob doesn't appear in portal | Portal doesn't show soft-deleted by default | Use "Show deleted blobs" in portal or --include d in CLI |
| Undelete fails with 404 error | Retention period already expired; blob was permanently removed | Act before period expires; increase period if necessary |
| Soft Delete accidentally disabled | Someone changed Data Protection settings | Use Azure Policy to prevent disabling or generate alert |
11. Operation and Maintenanceβ
11.1 Checking current Soft Delete statusβ
# Check complete data protection configuration
az storage account blob-service-properties show \
--account-name myaccount \
--resource-group myRG \
--query "{
blobSoftDelete: deleteRetentionPolicy,
containerSoftDelete: containerDeleteRetentionPolicy,
versioning: isVersioningEnabled,
changeFeed: changeFeed
}"
11.2 Monitoring volume of soft-deleted blobsβ
In Azure Monitor:
az monitor metrics list \
--resource <storage-account-id> \
--metric BlobCapacity \
--dimension BlobType \
--interval PT1H
The value returned with BlobType=SoftDeletedBlob indicates how much space is being occupied by soft-deleted data.
Configure an alert to detect abrupt increases:
az monitor metrics alert create \
--name "soft-deleted-spike" \
--resource-group myRG \
--scopes <storage-account-id> \
--condition "total BlobCapacity > 10000000000" \
--condition-dimension BlobType=SoftDeletedBlob \
--window-size 1h \
--evaluation-frequency 15m \
--action myActionGroup
11.3 Forcing early expiration (purge)β
In scenarios where you need to free up space immediately (soft-deleted test data, for example), you can purge soft-deleted blobs via REST API or SDK:
from azure.storage.blob import BlobServiceClient
client = BlobServiceClient.from_connection_string(conn_str)
blob_client = client.get_blob_client(container="mycontainer", blob="test-blob.txt")
# Purge soft-deleted version (requires specific version)
blob_client.delete_blob(delete_snapshots="include", version_id="<version-id>")
This operation is irreversible. Only use when certain the data is not needed.
11.4 Important limitsβ
| Aspect | Limit |
|---|---|
| Minimum retention period | 1 day |
| Maximum retention period | 365 days |
| Soft Delete available on account types | Standard GPv2, Premium Block Blob, Standard GPv1 (blob only) |
| Container Soft Delete on Premium | Available |
| Cost of soft-deleted data | Charged at blob tier at time of deletion |
| Soft Delete applies to | Block Blobs, Append Blobs, Page Blobs, Snapshots, Versions |
12. Integration and Automationβ
12.1 Restoration automation with Azure Functionsβ
To create an automated system for detecting and alerting deletions:
import azure.functions as func
from azure.storage.blob import BlobServiceClient
import logging
def main(timer: func.TimerRequest):
"""
Runs daily and lists all soft-deleted blobs,
sending alert if volume exceeds threshold.
"""
client = BlobServiceClient.from_connection_string(conn_str)
soft_deleted_count = 0
for container in client.list_containers():
for blob in client.get_container_client(container['name']).list_blobs(include=['deleted']):
if blob['deleted']:
soft_deleted_count += 1
logging.warning(f"Blob soft-deleted: {container['name']}/{blob['name']}")
if soft_deleted_count > 100:
# Trigger alert via Logic Apps, Teams or email
logging.error(f"ALERT: {soft_deleted_count} soft-deleted blobs detected!")
12.2 Azure Policy: DeployIfNotExists for Soft Deleteβ
Create a policy that automatically enables Soft Delete on new Storage Accounts:
{
"if": {
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
},
"then": {
"effect": "DeployIfNotExists",
"details": {
"type": "Microsoft.Storage/storageAccounts/blobServices",
"existenceCondition": {
"field": "Microsoft.Storage/storageAccounts/blobServices/deleteRetentionPolicy.enabled",
"equals": true
},
"deployment": {
"properties": {
"mode": "incremental",
"template": {
"$schema": "...",
"resources": [{
"type": "Microsoft.Storage/storageAccounts/blobServices",
"name": "[concat(parameters('storageAccountName'), '/default')]",
"properties": {
"deleteRetentionPolicy": {
"enabled": true,
"days": 7
},
"containerDeleteRetentionPolicy": {
"enabled": true,
"days": 30
}
}
}]
}
}
}
}
}
}
13. Final Summaryβ
Essential concepts:
- Soft Delete works like a recycle bin: deleted data stays in soft-deleted state for a configurable period (1 to 365 days) and can be restored during this period.
- There are two independent mechanisms: Blob Soft Delete and Container Soft Delete, each configured with its own retention period.
- Soft-deleted data is invisible in normal listings but continues occupying space and being charged.
- Soft Delete protects against deletion, not against overwrite. For protection against content modification, combine with Blob Versioning.
Critical differences:
- Blob Soft Delete vs Container Soft Delete: Blob protects individual files; Container protects the entire container with all its content. Must be configured separately.
- Soft Delete vs Immutability Policy: Soft Delete is post-deletion recovery. Immutability prevents deletion before it occurs.
- Soft Delete vs Blob Versioning: Soft Delete recovers deleted blobs. Versioning maintains version history of a modified blob. They are complementary, not exclusive.
- Restore blob vs restore container:
Undelete Blobrestores an individual blob.Restore Containerrestores the container and all blobs that were in it.
What needs to be remembered:
- Enable Soft Delete on every production Storage Account as minimum standard practice.
- The retention period must be configured before any deletion. Soft Delete doesn't retroact for deletions prior to enablement.
- Soft-deleted containers reserve the name: it's not possible to create another container with the same name until the soft-deleted one expires or is explicitly restored.
- The Undelete operation restores the blob and all its snapshots simultaneously.
- Soft-deleted data can be purged early via API by users with delete permission. For protection against this, use Immutability Policies.
- Monitor the volume of
SoftDeletedBlobin Azure Monitor to control costs and detect anomalous deletion patterns.