Azure Blob Storageへアクセスした際に403 Forbiddenが返っても、直すべき設定が「権限」とは限りません。SASの期限切れや署名不一致、Azure RBACのデータ操作権限不足、ストレージファイアウォールによる拒否など、異なる原因が同じHTTP 403として表れます。
最初に確認するのは、権限設定画面ではなく403に付随する詳細エラーコードと、使用している認証方式です。AuthenticationFailedなら認証情報、AuthorizationPermissionMismatchなら操作権限、AuthorizationFailureならネットワーク制限を中心に調べます。HTTPステータスだけを見て、匿名公開や「すべてのネットワークから有効」へ変更してはいけません。Azure Blob Storageの403には、原因を絞り込むための詳細エラーコードが返されます。([Microsoft Learn][1])
Azure Blob Storageの403は詳細エラーコードで切り分ける
Azure Blob Storageで403が発生したら、まずレスポンス本文、SDKの例外、クライアントのログ、Azureのリソースログなどから詳細エラーコードを確認します。
代表的なコードと、最初に調べる対象は次のとおりです。
| 詳細エラーコード | 主な原因 | 最初に確認する設定 |
|---|---|---|
AuthenticationFailed | SASの期限、開始時刻、署名、キー、形式が不正 | SASパラメーター、ストレージキー、対象アカウント |
KeyBasedAuthenticationNotPermitted | Shared Key認証が無効 | アプリの認証方式、ストレージアカウントのShared Keyポリシー |
AuthorizationPermissionMismatch | 認証はできたが、操作権限が不足 | SASのsp、Azure RBACのデータアクセスロール |
AuthorizationServiceMismatch | SASが別のStorageサービス向け | Account SASのss、接続先サービス |
AuthorizationFailure | 公開ネットワーク、IP、VNet、ファイアウォールなどによる拒否 | ネットワークアクセス、IP規則、VNet、Private Endpoint |
AuthenticationFailedとAuthorizationPermissionMismatchは似ていますが、意味は異なります。前者は資格情報を正しく検証できない状態、後者は資格情報を検証できたものの、要求した操作が許可されていない状態です。
また、AuthorizationFailureは必ずしもAzure RBACの問題ではありません。公開ネットワークアクセスが無効、接続元IPが許可されていない、対象サブネットがVNet規則に登録されていないといったネットワーク設定でも発生します。([Microsoft Learn][1])
設定を変更する前に記録する項目
調査途中でSASを再発行したり、役割を追加したりすると、何が原因だったのか分からなくなります。最初に失敗条件を固定して記録してください。
| 記録する項目 | 記録内容 |
|---|---|
| 失敗した操作 | Blobの一覧取得、ダウンロード、アップロード、上書き、削除など |
| 対象リソース | ストレージアカウント、コンテナー、Blobのパス |
| 詳細エラー | HTTPステータス、詳細エラーコード、エラーメッセージ |
| 認証方式 | Microsoft Entra ID、マネージドID、サービスプリンシパル、SAS、アカウントキー |
| 使用する主体 | ユーザー、アプリ、マネージドIDなどのオブジェクトID |
| 接続元 | ローカルPC、社内ネットワーク、VM、App Service、Functionsなど |
| 発生時刻 | タイムゾーンを含む日時 |
| 対象環境 | 開発、検証、本番、対象サブスクリプション |
特に重要なのは、どのIDでアクセスしているかです。ローカル開発環境では開発者アカウント、Azure上ではマネージドIDが選択されるなど、同じコードでも実行環境によって認証主体が変わる場合があります。
SASのクエリ文字列やアカウントキーは資格情報です。チケット、チャット、GitHub Issue、公開ログへ全文を貼り付けてはいけません。調査記録には認証方式、期限、権限の種類だけを残し、sigを含むSAS全文はマスクします。
AuthenticationFailedはSAS・キー・時刻を確認する
AuthenticationFailedでは、Azure RBACを変更する前に、SASやShared Keyが正しく成立しているかを確認します。
SASの有効期間を確認する
SASでは、主に次の時刻を確認します。
st:利用開始時刻se:有効期限
有効期限が切れていないかだけでなく、開始時刻が未来になっていないかも確認してください。
SASをすぐに利用する場合、開始時刻を現在時刻ぴったりに設定すると、SASを発行した端末とAzure側の時刻差によって「まだ有効ではない」と判定されることがあります。即時利用するSASでは開始時刻を省略するか、時刻差を考慮して設定します。
また、次の点も確認します。
seがstより後になっているか- アプリを動かす端末の日時が大きくずれていないか
- UTCと日本時間を取り違えていないか
- 古いSASを設定ファイルや環境変数から読み込んでいないか
- Stored Access Policy側で期限が短縮されていないか
Microsoft Learnでも、SASの期限切れ、開始時刻、クロックスキューがAuthenticationFailedの代表的な原因として挙げられています。([Microsoft Learn][1])
署名とストレージキーを確認する
エラー詳細に署名不一致を示すメッセージがある場合は、次を確認します。
- SASを発行したストレージアカウントと接続先が一致しているか
- Primary KeyとSecondary Keyを取り違えていないか
- SAS発行後にストレージキーを再生成していないか
- SASをURLへ組み込む過程で文字列が変化していないか
&や%などが設定ファイルやシェルで意図せず変換されていないか- SASの先頭にある
?の有無を、SDKや接続文字列の仕様に合わせているか
キーを再生成すると、そのキーで署名した既存SASが使用できなくなることがあります。ローテーション後は、アプリ、Key Vault、CI/CDのシークレット、コンテナー環境変数などに古いキーやSASが残っていないか確認します。
SASの種類と対象範囲を確認する
SASが有効でも、要求する操作とSASの種類が合わなければ失敗します。
たとえば、特定コンテナーやBlob向けのService SASを使って、ストレージアカウント全体のコンテナー一覧を取得することはできません。アカウント単位の操作には、操作内容に対応したAccount SASなどが必要です。
Account SASを使用する場合は、ssにBlobサービスを表すbが含まれているかも確認します。AuthorizationServiceMismatchが返る場合は、BlobではなくFile、Queue、Table向けに発行したSASを使用していないかを調べます。([Microsoft Learn][1])
Shared Keyが禁止されていないか確認する
KeyBasedAuthenticationNotPermittedが返る場合、ストレージアカウントでShared Key認証が無効になっています。
この場合、アカウントキーやキーを含む接続文字列を修正しても解決しません。次のどちらかを選択する必要があります。
- アプリをMicrosoft Entra IDまたはマネージドID認証へ変更する
- セキュリティ方針を確認したうえでShared Key認証を再び許可する
403を解消するためだけにShared Keyを再有効化するのではなく、Azure上で動くアプリではマネージドIDを優先するのが安全です。Microsoftも、可能な場合はMicrosoft Entra IDとマネージドIDを利用し、SASが必要な場合はUser Delegation SASを利用することを推奨しています。([Microsoft Learn][2])
AuthorizationPermissionMismatchは操作権限を確認する
AuthorizationPermissionMismatchは、認証に成功した後の認可で拒否されている状態です。
SASを使用している場合と、Microsoft Entra IDを使用している場合では確認箇所が異なります。
SASのspに必要な権限があるか確認する
SASのspには、そのSASで許可する操作が記録されています。たとえば、読み取りだけを許可したSASでは、Blobのアップロードや削除はできません。
確認すべき代表的な操作は次のとおりです。
| 実行したい操作 | 確認する権限 |
|---|---|
| Blobの読み取り | Read |
| Blob一覧の取得 | List |
| Blobの作成・更新 | WriteまたはCreate |
| Blobの削除 | Delete |
| Blobの追加 | Add |
一つの操作で複数の権限が必要になる場合もあります。Microsoftのトラブルシューティング資料では、Blobの上書きでWriteとDeleteの両方が必要になるケースが例示されています。エラーになったAPI操作に必要な権限を確認し、必要なものだけをSASへ追加してください。([Microsoft Learn][1])
SASを作り直す際に、読み取り、書き込み、削除、一覧取得をすべて付ける方法は避けます。原因となった操作を特定し、最小限の権限だけを追加する方が安全です。
Azure RBACではデータアクセスロールを確認する
Microsoft Entra ID、サービスプリンシパル、マネージドIDを使用している場合は、対象のセキュリティプリンシパルにBlobデータ用のロールが割り当てられているか確認します。
代表的なロールは次のとおりです。
| 用途 | 代表的なロール |
|---|---|
| Blobデータの読み取り | Storage Blob Data Reader |
| Blobデータの読み取り、書き込み、削除 | Storage Blob Data Contributor |
| 所有権やADLS Gen2のPOSIXアクセス制御を管理 | Storage Blob Data Owner |
| User Delegation SAS用の委任キーを取得 | Storage Blob Delegator |
ロール名だけでなく、誰に、どのスコープで割り当てたかを確認する必要があります。
- 実際に動作しているマネージドIDのオブジェクトIDか
- システム割り当てIDとユーザー割り当てIDを取り違えていないか
- 対象コンテナーを含むスコープか
- 別のストレージアカウントへ割り当てていないか
- Deny Assignmentや条件付きロール割り当てで拒否されていないか
ロールのスコープは、必要に応じてコンテナー、ストレージアカウント、リソースグループ、サブスクリプションへ設定できます。原則として、対象コンテナーやストレージアカウントなど、必要最小限のスコープを選びます。([Microsoft Learn][2])
OwnerやContributorだけではBlobデータへアクセスできない
Azureで混同しやすいのが、管理プレーンとデータプレーンの権限です。
- 管理プレーン:ストレージアカウントの作成、設定変更、ネットワーク構成など
- データプレーン:Blobの一覧取得、読み取り、アップロード、削除など
サブスクリプションやストレージアカウントのOwner、Contributor、Storage Account Contributorは、Microsoft Entra IDによるBlobデータアクセスを自動的に許可するロールではありません。Blobデータへアクセスするには、原則としてStorage Blob Data Readerなど、データ操作を含むロールが必要です。([Microsoft Learn][2])
ただし、管理ロールにストレージキーの取得権限が含まれている場合、Azure portalがShared Keyを使用してデータへアクセスすることがあります。そのため、ポータルでは見えるのに、マネージドIDを使用するアプリでは403になるという状況も起こり得ます。
Azure portalではReaderロールも確認する
Azure portalからMicrosoft Entra ID認証でBlobデータを表示する場合、データアクセスロールに加えて、ストレージアカウントをポータル上で参照するためのAzure Resource Manager側の権限も必要です。
たとえば、次の組み合わせです。
- Storage Blob Data Reader
- Reader
データアクセスロールだけを付与しても、Azure portalの画面をたどるための管理プレーン権限が不足していると、期待どおりに操作できないことがあります。([Microsoft Learn][3])
なお、Azure RBACの変更は即時に反映されない場合があります。割り当て対象とスコープが正しいことを確認したうえで、反映時間を考慮して同じ条件で再試行します。
AuthorizationFailureはネットワーク設定を確認する
AuthorizationFailureでは、Azure RBACを広げる前にネットワーク経路を確認します。
主な確認対象は次のとおりです。
- 公開ネットワークアクセスの許可状態
- ストレージファイアウォール
- 接続元のグローバルIPアドレス
- VNetとサブネットの許可規則
- Service Endpoint
- Resource Instance Rule
- 信頼されたAzureサービスの例外
- Network Security Perimeter
- Private EndpointとDNS
公開エンドポイントのアクセス制限を確認する
ストレージアカウントの公開エンドポイントへ接続している場合、次の順番で確認します。
- 公開ネットワークアクセスが無効になっていないか
- 選択したネットワークだけを許可する設定になっていないか
- 接続元のグローバルIPアドレスが許可されているか
- 対象のVNetとサブネットが許可されているか
- サブネットで必要なService Endpointが有効か
- Azureサービスからの接続なら、Resource Instance Ruleや例外設定が適切か
IP規則へ登録するのは、PCに設定された192.168.x.xなどのプライベートIPではありません。プロキシ、VPN、NAT Gateway、社内ファイアウォールなどを通過した後、Azure Storageから見える送信元のグローバルIPを確認します。
Azure Storageのネットワーク規則を有効にすると、明示的に許可された接続元以外は公開エンドポイントへ接続できません。また、許可されたネットワークから接続できても、認証と認可の条件は別途満たす必要があります。([Microsoft Learn][4])
Azure portalからの操作も接続元ネットワークの影響を受ける
「Azure portalから操作しているのでAzure内部からの接続になる」とは限りません。
Blobデータをポータルから表示する操作では、ブラウザーを実行しているネットワークのIPアドレスがストレージファイアウォールの影響を受けることがあります。そのため、次のような現象が起こります。
- Azure VM上のアプリからは成功する
- 自宅や社内PCのAzure portalからは403になる
- VPN接続中だけ失敗する
- 社内ネットワークでは成功するがモバイル回線では失敗する
ポータル操作だけが失敗するときも、RBACだけでなく、ブラウザー側の接続元IPとネットワーク規則を確認してください。([Microsoft Learn][1])
VNetを許可しただけで終わらせない
ストレージアカウントを特定のサブネットから利用する場合、ストレージ側のVNet規則と、サブネット側のService Endpoint設定が対応しているか確認します。
また、アプリがVNet統合されていても、実際のストレージ向け通信が想定したサブネットから出ているとは限りません。アプリの統合先サブネット、ルート、NAT、DNSを含めて確認します。
「同じVNetにあるから接続できるはず」ではなく、実際にどの経路でストレージエンドポイントへ到達しているかを確認することが重要です。
Private EndpointではDNSの解決先を確認する
Private Endpointを作成していても、クライアントがストレージアカウント名を公開IPへ名前解決していれば、Private Endpoint経由にはなりません。
実際にアプリを動かしている端末やVMから、次のように名前解決を確認します。
Resolve-DnsName <storage-account>.blob.core.windows.net
または次のコマンドを使用します。
nslookup <storage-account>.blob.core.windows.net
意図したVNetやオンプレミスネットワークから実行したとき、ストレージアカウントの名前がPrivate EndpointのプライベートIPへ解決されるかを確認します。
公開IPへ解決される場合は、次の設定を調べます。
privatelink.blob.core.windows.netのPrivate DNS Zoneが存在するか- Private DNS Zoneがクライアント側VNetへリンクされているか
- 独自DNSサーバーからPrivate DNS Zoneへ転送できるか
- VPNやExpressRoute経由のクライアントが適切なDNSサーバーを参照しているか
- Private Endpointの接続が承認済みか
- 接続先サブリソースが
blobになっているか
アプリの接続先を<storage-account>.privatelink.blob.core.windows.netへ直接変更するのは推奨されません。通常の<storage-account>.blob.core.windows.netを使用し、DNSによってPrivate Endpointへ誘導します。([Microsoft Learn][5])
ADLS Gen2ではblobとdfsの両方を確認する
階層型名前空間を有効にしたAzure Data Lake Storage Gen2では、操作によってBlobエンドポイントとDFSエンドポイントの間を行き来することがあります。
そのため、構成によっては次の両方のPrivate Endpointが必要です。
blobdfs
片方だけを作成すると、通常のBlob操作は成功しても、ディレクトリ作成、ACL管理、削除など特定の操作だけが失敗する場合があります。([Microsoft Learn][5])
Blobコピーでは送信元と送信先の両方を確認する
ストレージアカウント間でBlobをコピーする場合、接続元クライアントまたはサービスが、コピー元とコピー先の両方へネットワークアクセスできる必要があります。
コピー先だけにPrivate Endpointを設定しても、コピー元の公開アクセスが拒否されていれば処理は失敗します。認証情報と権限についても、コピー元とコピー先を分けて確認してください。([Microsoft Learn][1])
原因となる設定だけを修正して再試行する
403の原因を特定したら、該当する設定だけを修正します。
再試行では、次の条件を変えないことが重要です。
- 同じ操作
- 同じストレージアカウント
- 同じコンテナーまたはBlob
- 同じ認証主体
- 同じ認証方式
- 同じ接続元ネットワーク
- 同じアプリまたはツール
たとえば、App ServiceのマネージドIDで発生した403を、管理者のPCからアカウントキーを使って確認しても、元の問題が解決したかは判断できません。
修正は一つずつ行います。
- 詳細エラーコードから原因の種類を決める
- 原因候補となる設定を一つ修正する
- 同じ条件で再試行する
- 詳細エラーコードが変化したか確認する
- 成功するまで次の層を確認する
たとえば、AuthenticationFailedからAuthorizationPermissionMismatchへ変化した場合、認証情報の問題は解消し、次に権限不足が表面化した可能性があります。エラーコードの変化も調査の手掛かりになります。
403を解消するために避けるべき対応
| 避ける対応 | 問題点 |
|---|---|
| コンテナーやBlobを匿名公開する | 本来不要な第三者アクセスを許す可能性がある |
| すべてのネットワークからのアクセスを許可する | ファイアウォールによる防御範囲を失う |
| サブスクリプション全体でOwnerを付与する | Blobデータ権限の問題を解決できない場合があり、権限過剰になる |
| SASへ全権限を付ける | 漏えい時の影響が大きくなる |
| 複数の設定を同時に変更する | 原因が分からなくなり、元に戻しにくい |
| SASやアカウントキーをログへ出す | 資格情報の漏えいにつながる |
| エラーのたびにキーを再生成する | 正常に動いている別システムまで停止させる可能性がある |
ネットワーク設定を確認する場合も、「すべてのネットワーク」を許可して試すのではなく、許可済みのVMや管理端末など、条件が分かっている接続元で比較します。
代表的なコードに当てはまらない場合の確認項目
AuthenticationFailed、AuthorizationPermissionMismatch、AuthorizationFailureの確認だけで解決しない場合は、次の項目も調べます。
- HTTPSが必須なのにHTTPで接続していないか
- Stored Access PolicyがSASの権限や期限を制限していないか
- Stored Access Policyの変更直後で、反映待ちになっていないか
- ADLS Gen2のACLに実行主体が含まれているか
- 親ディレクトリに必要な実行権限があるか
- Sticky Bitによって削除や名前変更が拒否されていないか
- コンテナーの暗号化スコープと要求時の指定が競合していないか
- 顧客管理キーが無効になっていないか
- ストレージアカウントやサブスクリプションが無効になっていないか
- Network Security PerimeterやService Endpoint Policyで拒否されていないか
- コピー元とコピー先の双方へアクセスできるか
Azure Blob Storageの403は、SAS、RBAC、ファイアウォールだけでなく、ACL、暗号化スコープ、アカウント状態などでも発生します。代表的な三分類で解決しない場合は、詳細エラーメッセージとリソースログを基に対象を広げます。([Microsoft Learn][1])
Azure Blob Storageの403は設定を広げず原因を絞る
Azure Blob Storageで403が発生したときは、次の順番で対応します。
- HTTP 403だけで判断せず、詳細エラーコードを取得する
- 使用中の認証方式と、実際の認証主体を確認する
AuthenticationFailedならSAS、時刻、署名、キーを確認するAuthorizationPermissionMismatchならSAS権限とBlobデータ用RBACを確認するAuthorizationFailureなら公開アクセス、IP、VNet、Private Endpoint、DNSを確認する- 原因となる設定だけを修正する
- 同じID、操作、接続元ネットワークで再試行する
最初にファイアウォールを全面開放したり、強いロールを追加したりするのではなく、詳細エラーコードから認証、権限、ネットワークの順に切り分けることが、安全かつ確実な解決方法です。
[1]: https://learn.microsoft.com/en-us/troubleshoot/azure/azure-storage/blobs/authentication/storage-troubleshoot-403-errors “Troubleshoot 403 errors in Azure Blob Storage – Azure | Microsoft Learn”
[2]: https://learn.microsoft.com/en-us/azure/storage/blobs/authorize-access-azure-active-directory “Authorize Blob Access with Microsoft Entra ID – Azure Storage | Microsoft Learn”
[3]: https://learn.microsoft.com/en-us/azure/storage/blobs/assign-azure-role-data-access “Assign an Azure Role for Blob Data Access – Azure Storage | Microsoft Learn”
[4]: https://learn.microsoft.com/en-us/azure/storage/common/storage-network-security “Azure Storage firewall rules and network access | Microsoft Learn”
[5]: https://learn.microsoft.com/en-us/azure/storage/common/storage-private-endpoints “Use private endpoints – Azure Storage | Microsoft Learn”

コメント