
Azure BlobのSASを期限前に止めると、ほかのURLはどうなる?6本のSASで失効の範囲を確かめた
どうも!オペ部の西村祐二です!
Azure Blob Storageのファイルを一時的に渡すために、SAS(共有アクセス署名)付きのURLを配布することがあります。そのURLが漏えいした場合や、配布先との契約が終了した場合、有効期限を待たずに止められるのでしょうか。
期限前に止める方法はあります。ただし、URLを1本だけ指定して取り消す操作はありません。止める対象は、SASが参照するポリシーか、署名に使った鍵です。そのため、同じポリシーや鍵を使うほかのURLも一緒に止まります。
この記事では、種類の違うSASを6本発行し、失効の操作をするたびに6本すべてのHTTPステータスを確かめました。どの操作でどのURLが止まり、反映に何秒かかったかをもとに、配布先ごとに止めたい場合の発行方法を考えます。2026年11月10日に、Azure CLI 2.91.0と東日本リージョンのストレージアカウントで試した結果です。
失効の操作ごとに止まったURL
ストレージアカウントには、key1とkey2の2本のアカウントキー(アクセスキー)があります。6本のSASの内訳は次のとおりです。
- サービスSASを4本。key1で署名し、ポリシーAに関連付けた1本、ポリシーBに関連付けた1本、ポリシーなしの1本と、key2で署名したポリシーなしの1本
- key1で署名したアカウントSASを1本
- ユーザー委任SASを1本
ポリシーは、コンテナーに名前を付けて保存する権限と有効期限の設定(保存されたアクセスポリシー)です。SASはその名前を参照します。
上から順に操作を行い、そのたびに6本を確かめた結果が次の表です。○は取得できた(200)、×は拒否された(403)を表します。操作は続けて行ったので、前の操作で止まったURLは、作り直したポリシーAを除いて×のままです。太字は、その操作で状態が変わったURLです。
| 操作 | ポリシーA | ポリシーB | ポリシーなし(key1) | ポリシーなし(key2) | アカウントSAS(key1) | ユーザー委任SAS | 反映 |
|---|---|---|---|---|---|---|---|
| 操作前 | ○ | ○ | ○ | ○ | ○ | ○ | - |
| ポリシーAを削除 | × | ○ | ○ | ○ | ○ | ○ | 直後 |
| 同じ名前でポリシーAを作り直す | ○ | ○ | ○ | ○ | ○ | ○ | 直後 |
| key2を再生成 | ○ | ○ | ○ | × | ○ | ○ | 直後 |
| key1を再生成 | × | × | × | × | × | ○ | 約30秒 |
| ユーザー委任キーを失効 | × | × | × | × | × | × | 10〜20秒 |
結果から分かったことは5つです。
- 配布先単位で、ほかのSASやアプリを巻き込まずに止められたのは、配布先ごとにポリシーを分けたサービスSASでした(key2の再生成で止まったのも1本ですが、key2で署名したSASが1本しかなかったためです)
- 削除したポリシーを同じ名前で作り直すと、止めたはずのSASがまた通りました
- key1の再生成では、ポリシーに関連付けたSASも止まりました。ポリシーに関連付けていても、署名にはアカウントキーを使うためです
- key1の再生成の直後は、約30秒のあいだ、古いキーで署名したSASで200と403が入れ替わりました
- ユーザー委任SASは、アカウントキーを2本とも再生成しても通り続け、ユーザー委任キーを失効させると10〜20秒後に止まりました
期限前に止める対象はURLではなく、ポリシーや鍵
SASは、対象のリソース、権限、有効期間などを指定して、限定的なアクセスを委任する仕組みです。トークンはURLのクエリに付けて使います。
公式の説明では、SASはクライアント側で生成でき、Azure Storageはトークンをまったく追跡しないとされています。そのため、期限前に止めるには、署名に使った鍵か、SASが参照するポリシーを無効にします。
Amazon S3の署名付きURLにも、一般に、URLの作成に使った認証情報を取り消したり削除したりすると、期限前でもURLが使えなくなるという説明があります。止める対象がURLではない点は似ています。Azureでは止める対象がポリシー、アカウントキー、ユーザー委任キーに分かれるので、どれを止めるかで一緒に止まる範囲が変わります。
| SASの種類 | 署名に使う鍵 | 期限前に止める方法 |
|---|---|---|
| ポリシーに関連付けたサービスSAS | アカウントキー | ポリシーの削除・変更、または署名したキーの再生成 |
| ポリシーに関連付けないサービスSAS | アカウントキー | 署名したキーの再生成 |
| アカウントSAS | アカウントキー | 署名したキーの再生成(保存されたアクセスポリシーは使えない) |
| ユーザー委任SAS | Microsoft Entra IDの資格情報で取得したユーザー委任キー | ユーザー委任キーの失効、または発行した主体のロールの変更 |
この表は、SASの概要、保存されたアクセスポリシー、ユーザー委任SASの失効の公式の説明をまとめたものです。
以下は自作した概念図で、公式の構成図ではありません。

なお、この記事では、利用者のEntra IDとの結び付けを要求するUser-bound user delegation SASは扱いません。
署名に使う鍵を変えて6本のSASを発行した
- Azure CLI 2.91.0(macOS)
- ストレージアカウント: 東日本リージョン、Standard_LRS、StorageV2。共有キーでのアクセスを許可
- コンテナー
share(匿名アクセスなし)に、テキストファイルreport.txtを1つ置く - 操作したのは、サブスクリプションの共同作成者ロールと、ストレージ BLOB データ共同作成者ロールを持つサービスプリンシパル(Azure CLIでサインイン済み)
ユーザー委任SASで読み取りを許可するには、発行する主体自身がBlobを読み取れる必要があります。そのため、データ操作のロール(ストレージ BLOB データ共同作成者)も付けています。
アカウント名とキーは、環境変数 AZURE_STORAGE_ACCOUNT と AZURE_STORAGE_KEY でAzure CLIに渡しました。最初は AZURE_STORAGE_KEY にkey1を入れたので、ポリシーに関連付けたSAS、ポリシーなしのサービスSAS、アカウントSASはkey1で署名されます。key2で署名したSASは、AZURE_STORAGE_KEY をkey2に変えて発行し、発行後にkey1に戻しました。--expiry の時刻はUTCで、記事では実行した日時を変数に入れています。
export AZURE_STORAGE_ACCOUNT=<storage-account>
export AZURE_STORAGE_KEY="$(az storage account keys list --resource-group <resource-group> --account-name <storage-account> --query "[?keyName=='key1'].value" -o tsv)"
expiry=$(date -u -v+2d '+%Y-%m-%dT%H:%MZ') # 2日後(macOS の date。記事の検証では 2026-11-11T15:48Z)
# 保存されたアクセスポリシーを2つ作る(読み取りだけ)
az storage container policy create --container-name share --name partner-a --permissions r --expiry "$expiry"
az storage container policy create --container-name share --name partner-b --permissions r --expiry "$expiry"
# ポリシーに関連付けたサービスSAS(権限と期限はポリシー側に持たせる)
# --policy-name だけを指定しても「--expiry と --permissions を指定しないで」という WARNING が出るが、SAS は発行される
az storage blob generate-sas --container-name share --name report.txt --policy-name partner-a -o tsv
# ポリシーに関連付けないサービスSAS
az storage blob generate-sas --container-name share --name report.txt --permissions r --expiry "$expiry" -o tsv
# アカウントSAS
az storage account generate-sas --services b --resource-types o --permissions r --expiry "$expiry" -o tsv
# ユーザー委任SAS(アカウントキーを使わず、サインイン中のMicrosoft Entra IDの資格情報で発行)
unset AZURE_STORAGE_KEY
az storage blob generate-sas --container-name share --name report.txt --permissions r \
--expiry "$(date -u -v+1d '+%Y-%m-%dT%H:%MZ')" --as-user --auth-mode login -o tsv
ユーザー委任SASの期限は、ユーザー委任キーの有効期間(最大7日)の範囲で、ほかより短い1日後にしました。
| 名前 | ログでの表記 | 種類 | 署名に使ったもの |
|---|---|---|---|
| ポリシーA | policy-a |
サービスSAS(ポリシー partner-a) |
key1 |
| ポリシーB | policy-b |
サービスSAS(ポリシー partner-b) |
key1 |
| ポリシーなし(key1) | adhoc-key1 |
サービスSAS | key1 |
| ポリシーなし(key2) | adhoc-key2 |
サービスSAS | key2 |
| アカウントSAS(key1) | account-key1 |
アカウントSAS | key1 |
| ユーザー委任SAS | user-delegation |
ユーザー委任SAS | ユーザー委任キー |
generate-sas が返すのはSASトークン(クエリ文字列)だけです。https://<storage-account>.blob.core.windows.net/share/report.txt?<SASトークン> のようにBlobのURLへ連結し、6本のトークンをそれぞれファイルに保存しました。確認には、次のような小さなスクリプトを使いました。操作の直後と、その後は5〜10秒おきに実行しています。
#!/usr/bin/env bash
# 6本のURLにGETし、時刻とHTTPステータスを1行に並べる(SASトークンは sas/ に1本ずつ保存してある)
line="$(date '+%T')"
for n in policy-a policy-b adhoc-key1 adhoc-key2 account-key1 user-delegation; do
code=$(curl -s -o /dev/null -w '%{http_code}' "https://<storage-account>.blob.core.windows.net/share/report.txt?$(cat sas/$n)")
line="$line $n=$code"
done
echo "$line"
以降のログは、その出力の抜粋です(時刻はJST)。
保存されたアクセスポリシーを削除すると、関連するSASだけが止まる
最初に、ポリシー partner-a を削除しました。
az storage container policy delete --container-name share --name partner-a
削除が終わった直後の確認で、ポリシーAだけが403になりました。同じコンテナーのポリシーBを含め、ほかの5本は200のままです。
00:49:22 policy-a=200 policy-b=200 adhoc-key1=200 adhoc-key2=200 account-key1=200 user-delegation=200 # 削除前
00:49:37 policy-a=403 policy-b=200 adhoc-key1=200 adhoc-key2=200 account-key1=200 user-delegation=200 # 削除後
ポリシーを削除したSASが拒否されたときの本文は、AuthenticationFailed で、詳細は SAS identifier cannot be found for specified signed identifier でした(別のポリシーで同じ操作をやり直して取得)。SASが参照するポリシーの名前(識別子)が見つからない、という理由です。
保存されたアクセスポリシーの説明では、ポリシーの削除や変更は、関連するSASにすぐ反映されると書かれています。今回も、削除の直後から拒否されました。
同じ名前で作り直すと、止めたSASがまた通る
次に、削除したポリシーと同じ名前 partner-a で、ポリシーを作り直しました。
az storage container policy create --container-name share --name partner-a --permissions r --expiry "$expiry"
作成直後の確認で、403になっていたポリシーAが200に戻り、止めたはずのURLがまた使える状態になりました。
00:49:59 policy-a=200 policy-b=200 adhoc-key1=200 adhoc-key2=200 account-key1=200 user-delegation=200 # 作り直した後
同じページには、ポリシーの作成・更新の反映に最大30秒かかることがあるとも書かれています。今回は直後の確認で切り替わりました。
サービスSASの失効の説明にも、同じ名前のポリシーを作り直すと、有効期限が残っている古いSASがまた有効になり得るという注意があります。
ポリシーは1つのコンテナーに5個まで
配布先ごとにポリシーを分ければ1社ずつ止められますが、ポリシーの数には上限があります。partner-c から partner-f まで追加したところ、5個目の partner-e までは作成できました。6個目の partner-f は、Azure CLIが送信前にエラーを返し、作成できませんでした。
ERROR: The command failed with an unexpected error. Here is the traceback:
ERROR: Too many access policies provided. The server does not support setting more than 5 access policies on a single resource.
(以降、トレースバックが続く)
公式の説明では、5個を超えて設定しようとするとサービスが400を返すとされています。今回はAzure CLIが送信前に止めたため、サーバーの応答は確かめていません。ポータルの「アクセス ポリシー」画面でも、ポリシーが5個あると「ポリシーの追加」が押せない状態になりました(赤枠は追記)。

アカウントキーを再生成すると、そのキーで署名したSASがまとめて止まる
まず、key2を再生成しました。Azure CLIの --key では、primary がkey1、secondary がkey2です。
az storage account keys renew --resource-group <resource-group> --account-name <storage-account> --key secondary
止まったのは、key2で署名したSASだけでした。key1で署名した4本とユーザー委任SASは、その後50秒ほど確認しても200のままでした。どちらのキーを再生成するかで止まるSASが変わるため、止めたいSASの署名に使ったキーを再生成する必要があります。
00:50:21 policy-a=200 policy-b=200 adhoc-key1=200 adhoc-key2=403 account-key1=200 user-delegation=200 # key2 再生成後
続けて、key1を再生成しました(--key primary)。key1で署名した4本が止まりました。この4本には、ポリシーに関連付けたSAS(ポリシーA、ポリシーB)も含まれます。
ただし、再生成の直後は、同じURLで200と403が入れ替わりました。
00:51:23 policy-a=200 policy-b=403 adhoc-key1=403 adhoc-key2=403 account-key1=403 user-delegation=200 # key1 再生成の直後
00:51:33 policy-a=403 policy-b=403 adhoc-key1=403 adhoc-key2=403 account-key1=403 user-delegation=200
00:51:43 policy-a=403 policy-b=403 adhoc-key1=403 adhoc-key2=403 account-key1=200 user-delegation=200
00:51:53 policy-a=403 policy-b=403 adhoc-key1=403 adhoc-key2=403 account-key1=403 user-delegation=200
再生成が終わった直後の確認では、ポリシーAがまだ通りました。20秒後には、アカウントSASが一度だけ200に戻っています。4本とも403になり、その後200に戻らなくなったのは、再生成からおよそ30秒後でした。どのサーバーが応答したかまでは見ていないので、200に戻った原因は切り分けていません。また、1回の計測なので、ほかのアカウントや時間帯で同じ秒数になるとは限りません。
アクセスキーの管理の説明は、キーを再生成すると、そのキーを使うアプリやAzureサービスにも影響すると警告しています。配布したSASだけでなく、接続文字列で同じキーを使うバッチなども止まります。
ユーザー委任キーを失効させると、アカウントのユーザー委任SASがまとめて止まる
ユーザー委任SASは、アカウントキーを2本とも再生成しても通り続けました。止めるには、ユーザー委任キーを失効させます。
az storage account revoke-delegation-keys --resource-group <resource-group> --name <storage-account>
このコマンドは、指定したストレージアカウントのユーザー委任キーをすべて失効させます。漏えいしたURLの発行に使ったキーだけを選ぶことはできません。
コマンドの完了から10秒後の確認ではまだ200で、20秒後の確認で403になりました。
00:52:32 ... user-delegation=200 # 失効の直後
00:52:42 ... user-delegation=200
00:52:52 ... user-delegation=403
ユーザー委任SASの失効の説明によると、ユーザー委任キーとロールの割り当てはAzure Storageにキャッシュされます。そのため、失効の操作から既存のSASが無効になるまでに遅れが出ることがあります。今回の10〜20秒は、10秒おきの確認で絞り込めた範囲です。1回の計測なので、ほかのアカウントや時間帯で同じ秒数になるとは限りません。
同じ説明では、SASを発行した主体のロールの割り当てやPOSIX ACLを変更・削除する方法でも、ユーザー委任SASを止められるとされています。この方法は今回試していないので、ロールを外してから止まるまでの秒数や、同じ主体が発行したほかのSASへの影響は確かめていません。
配布先Aだけを止めたいなら、発行する前に決める
同じBlobを取引先A社とB社に配り、「A社との契約が終わったらA社だけ止めたい」という要件で考えます。ここまでの結果と公式の説明から、選択肢ごとの向き不向きは次のようになります。
| 配り方 | A社だけ止められるか | 注意点 |
|---|---|---|
| A社とB社で同じポリシーに関連付けたサービスSAS | できない | ポリシーを削除するとB社も止まる |
| A社とB社でポリシーを分けたサービスSAS | できる(今回、ポリシーAだけ止まった) | 1コンテナーに5個まで。止めたポリシーの名前は再利用しない |
| ポリシーに関連付けないサービスSAS、アカウントSAS | 向かない | キーは2本しかなく、アプリも同じキーを使う。キーを再生成すると、そのキーのSASとアプリがすべて止まる |
| ユーザー委任SAS(発行する主体が1つ) | できない | 委任キーの失効はアカウント単位。止まるまで遅れがある |
| ユーザー委任SAS(配布先ごとに発行する主体を分ける) | 公式の説明に沿えば止められる(未検証) | 発行した主体のロールを外して止める方法。主体の管理が配布先の数だけ増える |
漏えいに気付いたときは、URLのクエリからどの操作が必要かを見分けられます。ポリシーに関連付けたサービスSASには、ポリシーの名前を表す si が入ります。ユーザー委任SASには、ユーザー委任キーを取得した主体を表す skoid が入ります(サービスSAS、ユーザー委任SASのパラメーターの説明)。key1とkey2のどちらで署名したかを示すパラメーターはないので、アカウントキーで署名する場合は、発行時にどちらのキーを使ったかを記録しておく必要があります。
Microsoftは、SASを使うならユーザー委任SASを推奨しています。アプリがアカウントキーを持たずに発行できるためです。ただ、今回の結果のとおり、発行する主体が1つなら、配布先を1社だけ止める用途には向きません。
自分なら、期限前に止める操作をなるべく使わずに済むよう、ユーザー委任SASの有効期間を短くし、期限が来たら正規の利用者にだけ再発行する運用をまず考えます。配布先が数社で、期限前に1社ずつ止めたい要件があるなら、配布先ごとに名前の違うポリシーを分けたサービスSASが選択肢になります。
配布先が多く、1社ずつ期限前に止める必要がある場合は、SASだけで要件を満たそうとせず、アプリ側で利用者を認証してからデータを返す方式と比べるのが良さそうです。
まとめ
Azure BlobのSASは期限前に止められますが、止める単位は1本のURLではなく、SASが参照するポリシーや署名に使った鍵です。実機では、ポリシーの削除で関連するSASだけが止まり、アカウントキーの再生成ではポリシーの有無にかかわらずそのキーのSASがまとめて止まりました。ユーザー委任SASは、ユーザー委任キーの失効から10〜20秒後に止まりました。
配布先ごとに期限前に止めたい場合の選び方は、次のとおりです。
- 配布先が数社で、1社ずつ止めたい: 配布先ごとに名前の違うポリシーを分けたサービスSAS(1コンテナーに5個まで、止めた名前は再利用しない)
- 期限前に止める必要がなければ: 有効期間を短くしたユーザー委任SASを、期限が来たら再発行する
- 配布先が多い: SASだけで済ませず、アプリ側で利用者を認証する方式と比べる
どれを選ぶにしても、配布先ごとに、どのポリシーを関連付けてどの鍵で署名するかを、配った後ではなく発行する前に決めておく必要がありそうです。
参考リンク
- Grant limited access to data with shared access signatures (SAS)
- Define a stored access policy
- Create a service SAS
- Create an account SAS
- Create a user delegation SAS
- Manage storage account access keys
- az storage account revoke-delegation-keys
- az storage container policy
- Download and upload objects with presigned URLs(Amazon S3)



