How Far Do Azure Storage Delete Locks Protect You? Sorting Out Measures Against Accidental Blob Deletion

How Far Do Azure Storage Delete Locks Protect You? Sorting Out Measures Against Accidental Blob Deletion

A delete lock on Azure Storage doesn't stop blob deletion or overwriting. Using the Azure CLI and portal, we confirm it only blocks management-plane operations, then sort out combining it with soft delete and versioning per account, container, and blob.
2026.11.09

This page has been translated by machine translation. View original

Hi there! I'm Yuji Nishimura from the Operations Department!

Putting a delete lock on an Azure Storage storage account prevents the account itself from being deleted by mistake. So, if you put a lock on an account that stores images, will the images (blobs) inside it also be protected from deletion?

A lock alone cannot prevent blobs from being deleted or overwritten. In a verification subscription, I tried deleting the account itself, a container, and a blob on a storage account with a delete lock. Only the deletion of the account and the deletion of a container through Azure Resource Manager (the management plane) were rejected. Even after switching to a read-only lock, I could still delete a blob using a key I had already obtained.

In this article, I check which operations a lock stops, using the official documentation and results on a real environment, and then organize the additional measures needed for each protection target (account, container, blob). Retention periods, cost estimates, deletion prevention with immutable storage, and recovery design including backups are out of scope. The materials I referred to are as of November 9, 2026.

A delete lock only stops management plane operations

There are two kinds of Azure resource locks. The official documentation for storage accounts describes their restrictions as follows.

Lock Restrictions on the storage account Deleting/overwriting stored blobs
CanNotDelete (delete lock) Prevents deleting the account. Reading and changing the configuration are still possible Not prevented
ReadOnly (read-only lock) Prevents deleting the account and changing its configuration. Reading the configuration is still possible Not prevented

"Read-only" here does not mean that the stored blob data becomes read-only. Making data impossible to delete or overwrite for a fixed period, like AWS S3 Object Lock, is the job of immutable storage, not resource locks.

Azure operations are divided into the management plane and the data plane. Management operations such as creating or deleting an account are sent to Azure Resource Manager, which manages Azure resources. Data operations such as reading and writing blobs are sent to the Blob service endpoint.

According to the official documentation on resource locks, locks apply only to management plane operations. They do not apply to data plane operations such as deleting or overwriting blobs.

The following diagram is a conceptual diagram I made myself, not an official architecture diagram. The upper row is the management plane path, and the lower row is the data plane path.

A self-made conceptual diagram of the scope of a delete lock. Deleting a storage account is sent to Azure Resource Manager on the management plane and is rejected by the delete lock placed on the account. Deleting or overwriting a blob is sent to the Blob service on the data plane and reaches the blob in the container without passing through the lock.

The lock itself can be deleted by users who have roles such as Owner or User Access Administrator. Because the account can also be deleted once the lock is removed, you need to narrow down the users who can manage locks, separately from data operation permissions.

Trying it out: checking what can be deleted on an account with a lock

In addition to the two paths in the diagram, I also tried deleting a container through the management plane and a read-only lock, using the Azure CLI and the Azure portal.

  • Date performed: November 9, 2026
  • Azure CLI 2.91.0 (macOS)
  • Storage account: East Japan region (japaneast), Standard_LRS, StorageV2. Shared key access was allowed (--allow-shared-key-access true), and it was created without specifying soft delete or versioning
  • User who performed the operations: a user with the Owner role on the subscription
  • After attaching a lock, I waited about 30 seconds before trying

On the account bvlock11092018, I created three containers, images, mgmt-test, and data-test, and placed cat.png and dog.png in images before testing. The contents are text of a few dozen bytes, and only the names resemble images.

For data operations on blobs and containers, I put the account name and account key in environment variables and authorized with --auth-mode key. I obtained the key first and kept using the same value even after switching to the read-only lock in step 5.

export AZURE_STORAGE_ACCOUNT=bvlock11092018
export AZURE_STORAGE_KEY="$(az storage account keys list --account-name bvlock11092018 \
  --resource-group blog-verify-azure-storage-lock-protection-scope --query '[0].value' -o tsv)"

1. Put a delete lock on the account

az lock create --name blog-verify-cannotdelete --lock-type CanNotDelete \
  --resource-group blog-verify-azure-storage-lock-protection-scope \
  --resource bvlock11092018 --resource-type Microsoft.Storage/storageAccounts \
  --notes "blog verification"

When you open "Locks" for the account in the portal, the lock you created is displayed with the lock type "Delete" (the red frame was added by me).

The Locks screen of a storage account in the Azure portal. The row of the lock with the lock type "Delete" and the scope set to the storage account is surrounded by a red frame.

2. Deleting the account is rejected

az storage account delete --name bvlock11092018 \
  --resource-group blog-verify-azure-storage-lock-protection-scope --yes
ERROR: (ScopeLocked) The scope '/subscriptions/<subscription-id>/resourceGroups/blog-verify-azure-storage-lock-protection-scope/providers/Microsoft.Storage/storageAccounts/bvlock11092018' cannot perform delete operation because following scope(s) are locked: '/subscriptions/<subscription-id>/resourcegroups/blog-verify-azure-storage-lock-protection-scope/providers/Microsoft.Storage/storageAccounts/bvlock11092018'. Please remove the lock and try again.

Even when run by a user with the Owner role, the deletion was rejected with ScopeLocked, and the storage account remained. In the portal, the lock is detected as soon as you open "Delete" on the overview page, a warning appears, and the "Delete" button cannot be pressed (the red frame was added by me).

The delete screen of a storage account in the Azure portal. The warning that the account cannot be deleted because it holds a delete lock, and the disabled delete button, are surrounded by a red frame.

3. Deleting and overwriting blobs succeeds

With the same lock still in place, I deleted dog.png and overwrote cat.png with different content.

az storage blob delete --container-name images --name dog.png --auth-mode key
az storage blob upload --container-name images --name cat.png --file cat-v2.txt --overwrite --auth-mode key
az storage blob list --container-name images --auth-mode key \
  --query '[].{name:name,size:properties.contentLength}' -o table
Name     Size
-------  ------
cat.png  27

Both succeeded. dog.png disappeared from the list, and cat.png was replaced with 27 bytes of content instead of 13 bytes. This matches the lower path in the diagram.

4. Deleting a container gives different results depending on the destination

Storage accounts also have APIs for operating on containers and other resources through the management plane. According to the official documentation on resource locks, operations on this path are protected by locks.

Container deletion also comes in two forms: Blob Containers - Delete on the management plane, and Delete Container on the data plane. In the Azure CLI, az storage container-rm corresponds to the former and operates on containers through the Microsoft.Storage resource provider. The latter is az storage container.

# Via the management plane (Azure Resource Manager)
az storage container-rm delete --storage-account bvlock11092018 \
  --resource-group blog-verify-azure-storage-lock-protection-scope --name mgmt-test --yes
ERROR: (ScopeLocked) The scope '/subscriptions/<subscription-id>/resourceGroups/blog-verify-azure-storage-lock-protection-scope/providers/Microsoft.Storage/storageAccounts/bvlock11092018/blobServices/default/containers/mgmt-test' cannot perform delete operation because following scope(s) are locked: '/subscriptions/<subscription-id>/resourcegroups/blog-verify-azure-storage-lock-protection-scope/providers/Microsoft.Storage/storageAccounts/bvlock11092018'. Please remove the lock and try again.
# Via the data plane (Blob service)
az storage container delete --name data-test --auth-mode key -o tsv
True

Deletion via the management plane was rejected by the lock placed on the account. Deletion via the data plane went through as is, and data-test was removed.

The official documentation recommends using management plane operations for storage accounts. However, which API is used differs depending on the tool or command. Even if deletion via the management plane is rejected, a user with data operation permissions can delete via the data plane. For this reason, I consider protecting containers not with locks but with soft delete, described later.

5. Even with a read-only lock, a blob can be deleted with an already-obtained key

A ReadOnly lock also stops List Keys, which retrieves account keys. According to the official documentation, this is because List Keys is an HTTPS POST operation, and a read-only lock rejects all POST operations.

With the key still in the environment variable, I switched the lock from CanNotDelete to ReadOnly.

az lock delete --name blog-verify-cannotdelete \
  --resource-group blog-verify-azure-storage-lock-protection-scope \
  --resource bvlock11092018 --resource-type Microsoft.Storage/storageAccounts
az lock create --name blog-verify-readonly --lock-type ReadOnly \
  --resource-group blog-verify-azure-storage-lock-protection-scope \
  --resource bvlock11092018 --resource-type Microsoft.Storage/storageAccounts \
  --notes "blog verification"

After waiting about 30 seconds, I tried retrieving the key.

az storage account keys list --account-name bvlock11092018 \
  --resource-group blog-verify-azure-storage-lock-protection-scope
ERROR: (ScopeLocked) The scope '/subscriptions/<subscription-id>/resourceGroups/blog-verify-azure-storage-lock-protection-scope/providers/Microsoft.Storage/storageAccounts/bvlock11092018' cannot perform write operation because following scope(s) are locked: '/subscriptions/<subscription-id>/resourcegroups/blog-verify-azure-storage-lock-protection-scope/providers/Microsoft.Storage/storageAccounts/bvlock11092018'. Please remove the lock and try again.

Retrieving the key was rejected as a write operation (write operation). The "Access keys" page in the portal also shows a ScopeLocked error, with the message "Cannot access the data plane because of a read lock on the resource or its parent." (the red frame was added by me).

The Access keys screen of the Azure portal. The ScopeLocked error and the detail that the data plane cannot be accessed because of the read lock are surrounded by a red frame.

However, what was stopped was retrieving the key. The official documentation also says that a client that already holds the key when the lock is applied can keep accessing data with that key. In fact, using the key obtained before the switch, I could delete cat.png even with the ReadOnly lock in place, and the container images became empty.

az storage blob delete --container-name images --name cat.png --auth-mode key
az storage blob list --container-name images --auth-mode key --query 'length(@)' -o tsv
0

According to the same documentation, users who do not have the key need to access data with Microsoft Entra ID credentials. I did not try operations using Entra ID credentials (data operation roles) this time. Whether ReadOnly has any effect in a configuration that does not use keys needs to be checked separately.

Only management plane operations were rejected

Operation tried Lock applied Destination Result
Delete the account CanNotDelete Management plane Rejected (ScopeLocked)
Delete/overwrite a blob CanNotDelete Data plane Succeeded
Delete a container (az storage container-rm) CanNotDelete Management plane Rejected (ScopeLocked)
Delete a container (az storage container) CanNotDelete Data plane Succeeded
Retrieve account keys ReadOnly Management plane Rejected (ScopeLocked)
Delete a blob with an already-obtained key ReadOnly Data plane Succeeded

Within the scope I tried, every rejected operation went through the management plane, and operations through the data plane succeeded under both locks.

Even when inherited from a resource group, data operations are not covered

Locks are inherited from a parent scope to child resources. For example, a delete lock placed on a resource group also applies to the storage accounts under it. Resources added later are also subject to inheritance.

However, inheritance only extends the range of resources the lock applies to, and data plane operations remain out of scope. Even if you lock an entire resource group, the lower path in the diagram does not pass through the lock, so a user with data operation permissions can delete the blobs inside. What I tried this time was an account-level lock. The explanation of resource-group-level locks is based on the official documentation.

Combine locks and recovery features for each protection target

For accidental deletion of blobs or containers, you use features other than locks. The data protection overview recommends, as a basic configuration, enabling soft delete for containers and blobs in addition to locking the account. In the comparison table by resource type in the same document, locks are also not counted as a feature that prevents container deletion.

The following table takes the case where an app stores images as block blobs (the common blob type for storing text and binary data) as an example, and summarizes the features to consider for each expected mistake. The table lists only the typical use of each feature.

Expected mistake Feature to consider Approach to protection
Deleting the storage account Delete lock on the account Prevent: rejects deleting the account
Deleting a container Soft delete for containers Restore: restores the container and its contents within the retention period
Deleting one image while leaving the container Soft delete for blobs Restore: restores the deleted blob within the retention period
Accidentally overwriting an image Blob versioning Restore: restores from a previous version

In the account I created with the Azure CLI without specifying soft delete or versioning this time, both were disabled.

az storage account blob-service-properties show --account-name bvlock11092018 \
  --resource-group blog-verify-azure-storage-lock-protection-scope \
  --query '{blobSoftDelete:deleteRetentionPolicy.enabled,containerSoftDelete:containerDeleteRetentionPolicy.enabled,versioning:isVersioningEnabled}' -o json
{
  "blobSoftDelete": false,
  "containerSoftDelete": null,
  "versioning": null
}

No values were set for container soft delete and versioning (null), and in the left side of the image in step 2 (the portal overview), blob soft delete, container soft delete, and versioning were all "Disabled". The dog.png I deleted in step 3 did not appear even in the list that includes deleted blobs (az storage blob list --include d), so it could not be recovered. Even with a lock in place, you cannot get back a blob you deleted by mistake with this setting. I did not try the default values when an account is created from the portal.

Container soft delete is used for restoring when an entire container has been deleted. It cannot be used when only individual blobs are deleted, so you also need to consider blob soft delete or blob versioning separately. With both container and blob soft delete, items past the retention period are permanently deleted. If you enable both, it seems good to align the retention periods. If the blob-side retention period is shorter, the blobs inside may already have been permanently deleted even if you restore the container.

On accounts where the hierarchical namespace (a namespace with a directory hierarchy, used by Data Lake Storage) is disabled, blob soft delete also has protection on overwrite. If versioning is disabled, the pre-overwrite state remains as a soft-deleted snapshot, and if it is enabled, it remains as a previous version.

Blob versioning is suited to continuously keeping the pre-overwrite state. However, storage charges also apply to past versions. It cannot be used on accounts with the hierarchical namespace enabled, and it is not a feature for recovering from deletion of the account or container itself.

I did not try deleting, overwriting, and restoring with soft delete or versioning enabled this time. The explanation that a snapshot or previous version remains after an overwrite and you can restore from it is based on the official documentation.

Summary

A delete lock on Azure Storage is a measure for preventing accidental deletion of the account itself. In my tests, only management plane operations were rejected, while deleting or overwriting blobs and deleting containers via the data plane went through. Even when inherited from a resource group, the protection scope does not extend to blob data operations. Operations that locks do not stop have to be restricted through data access permissions such as keys, SAS, and data operation roles.

Use locks to prevent account deletion, soft delete to restore containers and blobs, and versioning to keep the pre-overwrite state. Both soft delete and versioning must be enabled before a mistake happens. In the account I created with the Azure CLI without specifying settings, they remained disabled, so it would be good to check whether they are enabled on the accounts you use.

References

Microsoft Azure の利用費割引・活用サポート提供中!

クラスメソッドは、Microsoft Azureのうち特に生成AI領域に強みがあります。AWSの総合支援をメインに5,000社以上支援してきた実績をベースに、特にマルチクラウドでビジネスを最大化したいお客様に引き合いを頂いております。

Microsoft Azure 請求代行・技術支援サービスを詳しく見る

Share this article