
Azure Storageの削除ロックはどこまで守る?Blobの誤削除対策を整理する
どうも!オペ部の西村祐二です!
Azure Storageのストレージアカウントに削除ロックを付けると、アカウント自体の誤削除を防げます。では、画像を保存しているアカウントにロックを付ければ、中の画像(Blob)も削除されなくなるのでしょうか。
ロックだけでは、Blobの削除や上書きを防げません。検証用のサブスクリプションで、削除ロックを付けたストレージアカウントについて、アカウント自体、コンテナー、Blobの削除を試しました。拒否されたのは、アカウントの削除と、Azure Resource Manager経由(管理プレーン)のコンテナーの削除だけでした。読み取り専用ロックに付け替えても、取得済みのキーでBlobを削除できました。
この記事では、ロックが止める操作を公式ドキュメントと実機の結果で確かめ、保護対象(アカウント、コンテナー、Blob)ごとに追加で必要な対策を整理します。保持期間や費用の見積もり、不変ストレージによる削除防止、バックアップを含む復旧設計は扱いません。参照した資料は2026年11月9日時点のものです。
削除ロックが止めるのは、管理プレーンの操作
Azureのリソースロックには2種類あります。ストレージアカウントの公式資料では、それぞれの制限を次のように説明しています。
| ロック | ストレージアカウントへの制限 | 保存したBlobの削除・上書き |
|---|---|---|
CanNotDelete(削除ロック) |
アカウントの削除を防ぐ。構成の読み取り・変更は可能 | 防げない |
ReadOnly(読み取り専用ロック) |
アカウントの削除と構成の変更を防ぐ。構成の読み取りは可能 | 防げない |
ここでいう「読み取り専用」は、保存されたBlobデータを読み取り専用にするという意味ではありません。AWSのS3オブジェクトロックのように、データを一定期間削除・上書きできなくするのは、リソースロックではなく不変ストレージです。
Azureの操作は管理プレーンとデータプレーンに分かれます。アカウントの作成や削除などの管理操作は、Azureのリソースを管理するAzure Resource Managerへ送られます。Blobの読み書きなどのデータ操作は、Blobサービスのエンドポイントへ送られます。
リソースロックの公式資料によると、ロックが適用されるのは管理プレーンの操作だけです。Blobの削除や上書きなどのデータプレーン操作には適用されません。
次の図は自作した概念図で、公式の構成図ではありません。上段が管理プレーン、下段がデータプレーンの経路です。

ロック自体は、所有者(Owner)やユーザーアクセス管理者(User Access Administrator)などのロールを持つ利用者なら削除できます。ロックを外せばアカウントも削除できるため、ロックを管理できる利用者の範囲は、データ操作の権限とは別に絞っておく必要があります。
試してみる: ロックを付けたアカウントで何が消せるか確かめる
図の2つの経路に加えて、管理プレーン経由のコンテナーの削除と読み取り専用ロックも、Azure CLIとAzureポータルで試しました。
- 実施日: 2026年11月9日
- Azure CLI 2.91.0(macOS)
- ストレージアカウント: 東日本リージョン(
japaneast)、Standard_LRS、StorageV2。共有キーによるアクセスを許可(--allow-shared-key-access true)し、論理的な削除とバージョン管理は指定せずに作成 - 操作した利用者: サブスクリプションの所有者ロールを持つユーザー
- ロックは、付けてから30秒ほど待って試した
アカウントbvlock11092018に、コンテナーimages、mgmt-test、data-testの3つを作り、imagesにcat.pngとdog.pngを置いてから試しています。中身は数十バイトのテキストで、名前だけ画像に見立てています。
Blobとコンテナーのデータ操作は、アカウント名とアカウントキーを環境変数に入れ、--auth-mode keyで認可しました。キーは最初に取得し、手順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. アカウントに削除ロックを付ける
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"
ポータルでアカウントの「ロック」を開くと、作ったロックがロックの種類「削除」として表示されます(赤枠は追記)。

2. アカウントの削除は拒否される
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.
所有者ロールを持つユーザーで実行してもScopeLockedで拒否され、ストレージアカウントは残りました。ポータルでは、概要の「削除」を開いた時点でロックが検出され、警告が出て「削除」ボタンを押せない状態になります(赤枠は追記)。

3. Blobの削除と上書きは通る
同じロックを付けたまま、dog.pngを削除し、cat.pngを別の内容で上書きしました。
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
どちらも成功しました。dog.pngは一覧から消え、cat.pngは13バイトから27バイトの内容に置き換わっています。図の下段の経路のとおりです。
4. コンテナーの削除は、送り先によって結果が分かれる
ストレージアカウントには、コンテナーなどを管理プレーン経由で操作するAPIもあります。リソースロックの公式資料によると、この経路の操作はロックで保護されます。
コンテナーの削除にも、管理プレーンのBlob Containers - Deleteと、データプレーンのDelete Containerがあります。Azure CLIではaz storage container-rmが前者に当たり、Microsoft.Storageのリソースプロバイダー経由でコンテナーを操作します。後者はaz storage containerです。
# 管理プレーン経由(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.
# データプレーン経由(Blobサービス)
az storage container delete --name data-test --auth-mode key -o tsv
True
管理プレーン経由の削除は、アカウントに付けたロックで拒否されました。データプレーン経由の削除はそのまま通り、data-testは消えています。
公式資料は、ストレージアカウントでは管理プレーン経由の操作を使うよう推奨しています。ただ、どちらのAPIが使われるかは、ツールやコマンドによって異なります。管理プレーン経由の削除が拒否されても、データ操作の権限があればデータプレーン経由で削除できます。そのため、コンテナーの保護はロックではなく、後述する論理的な削除で考えます。
5. 読み取り専用ロックでも、取得済みのキーでBlobは消せる
ReadOnlyロックは、アカウントキーを取得するList Keysも止めます。公式資料によると、List KeysはHTTPSのPOST操作で、読み取り専用ロックではすべてのPOST操作が拒否されるためです。
環境変数にキーを入れた状態のまま、ロックをCanNotDeleteから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"
30秒ほど待ってから、キーの取得を試しました。
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.
キーの取得は、書き込み操作(write operation)として拒否されています。ポータルの「アクセス キー」もScopeLockedのエラーになり、「リソースまたはその親の読み取りロックが原因でデータ プレーンにアクセスできません。」と表示されます(赤枠は追記)。

ただし、止まったのはキーの取得です。公式資料にも、ロックを付けた時点でキーを持っているクライアントは、そのキーでデータにアクセスし続けられるとあります。実際に、付け替える前に取得したキーを使うと、ReadOnlyのままでもcat.pngを削除でき、コンテナーimagesは空になりました。
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
同じ資料によると、キーを持たない利用者は、Microsoft Entra IDの資格情報でデータにアクセスする必要があります。Entra IDの資格情報(データ操作のロール)を使った操作は、今回は試していません。キーを使わない構成でReadOnlyの影響がないかは、別に確かめる必要があります。
拒否されたのは管理プレーン経由の操作だけ
| 試した操作 | 付けたロック | 送り先 | 結果 |
|---|---|---|---|
| アカウントの削除 | CanNotDelete |
管理プレーン | 拒否(ScopeLocked) |
| Blobの削除・上書き | CanNotDelete |
データプレーン | 成功 |
コンテナーの削除(az storage container-rm) |
CanNotDelete |
管理プレーン | 拒否(ScopeLocked) |
コンテナーの削除(az storage container) |
CanNotDelete |
データプレーン | 成功 |
| アカウントキーの取得 | ReadOnly |
管理プレーン | 拒否(ScopeLocked) |
| 取得済みのキーでBlobの削除 | ReadOnly |
データプレーン | 成功 |
試した範囲では、拒否された操作はどれも管理プレーン経由で、データプレーン経由の操作はどちらのロックの下でも通りました。
リソースグループから継承しても、データ操作まで対象にはならない
ロックは親スコープから子リソースへ継承されます。たとえばリソースグループに付けた削除ロックは、その配下のストレージアカウントにも適用されます。後から追加したリソースも継承対象です。
ただし、継承で広がるのはロックを適用するリソースの範囲だけで、データプレーンの操作が対象外である点は変わりません。リソースグループ全体をロックしても、図の下段の経路はロックを通らないため、データ操作の権限を持つ利用者は中のBlobを削除できます。今回試したのはアカウント単位のロックです。リソースグループ単位のロックについては、公式資料に基づいて説明しています。
保護対象ごとに、ロックと復元機能を組み合わせる
Blobやコンテナーの誤削除には、ロックとは別の機能を使います。データ保護の概要では、アカウントのロックに加えて、コンテナーとBlobの論理的な削除を有効にする構成を基本として推奨しています。同じ資料のリソースの種類ごとの比較表でも、ロックはコンテナーの削除を防ぐ機能に数えられていません。
次の表は、アプリが画像をブロックBlob(テキストやバイナリデータを保存する一般的なBlobの種類)として保存する場合を例に、想定する誤操作ごとに検討する機能をまとめたものです。表には各機能の代表的な用途だけを載せています。
| 想定する誤操作 | 検討する機能 | 保護の考え方 |
|---|---|---|
| ストレージアカウントを削除する | アカウントの削除ロック | 防ぐ: アカウントの削除を拒否する |
| コンテナーを削除する | コンテナーの論理的な削除(soft delete) | 戻す: 保持期間内ならコンテナーと中身を復元する |
| コンテナーを残したまま、画像を1件削除する | Blobの論理的な削除(soft delete) | 戻す: 保持期間内なら削除したBlobを復元する |
| 画像を誤って上書きする | Blobのバージョン管理 | 戻す: 以前のバージョンから復元する |
今回、論理的な削除とバージョン管理を指定せずにAzure CLIで作ったアカウントでは、どちらも無効でした。
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
}
コンテナーの論理的な削除とバージョン管理は値が設定されておらず(null)、手順2の画像の左側(ポータルの概要)でも、Blobの論理的な削除、コンテナーの論理的な削除、バージョン管理はいずれも「無効」でした。手順3で削除したdog.pngは、削除済みのBlobを含めた一覧(az storage blob list --include d)にも出てこず、戻せない状態でした。ロックを付けていても、この設定のままでは誤って削除したBlobを取り戻せません。ポータルからアカウントを作った場合の初期値は試していません。
コンテナーの論理的な削除は、コンテナー全体が削除された場合の復元に使います。個別のBlobだけを削除した場合には使えないため、Blobの論理的な削除かBlobのバージョン管理も別に検討する必要があります。コンテナーとBlobのどちらの論理的な削除でも、保持期間を過ぎた対象は完全に削除されます。両方を有効にする場合は、保持期間をそろえておくのが良さそうです。Blob側の保持期間のほうが短いと、コンテナーを復元しても、中のBlobがすでに完全に削除されていることがあります。
階層型名前空間(Data Lake Storageで使う、ディレクトリ階層を持つ名前空間)が無効なアカウントでは、Blobの論理的な削除にも上書き時の保護があります。バージョン管理が無効なら、上書き前の状態が論理的に削除されたスナップショットとして残り、有効なら以前のバージョンとして残ります。
Blobのバージョン管理は、上書き前の状態を継続的に残す用途に向いています。ただし、過去バージョンにもストレージ料金がかかります。階層型名前空間を有効にしたアカウントでは使えず、アカウントやコンテナー自体の削除から復旧する機能でもありません。
論理的な削除やバージョン管理を有効にした状態での削除・上書きと復元は、今回は試していません。上書き後にスナップショットや以前のバージョンが残り、そこから戻せることは、公式資料に基づく説明です。
まとめ
Azure Storageの削除ロックは、アカウント自体の誤削除を防ぐための対策です。実際に試したところ、拒否されたのは管理プレーン経由の操作だけで、Blobの削除や上書き、データプレーン経由のコンテナーの削除は通りました。リソースグループから継承しても、Blobのデータ操作まで保護範囲は広がりません。ロックで止まらない操作は、キーやSAS、データ操作のロールといったデータへのアクセス権限で絞ることになります。
アカウントの削除防止にはロック、コンテナーやBlobの復元には論理的な削除、上書き前の状態の保持にはバージョン管理を使います。論理的な削除とバージョン管理は、どちらも誤操作の前に有効にしておく必要があります。Azure CLIで設定を指定せずに作ったアカウントでは無効のままだったので、使っているアカウントで有効になっているかを確認しておくと良さそうです。



