📦

Azure での BLOB のアクセス権(Action)を再考する

2023/11/02に公開
2

これは何...?

[ストレージBLOB共同作成者]ロールを付与していないのに BLOB ストレージの管理ができていることを不思議に思ったことはないでしょうか。[共同作成者]ロールを付けたりしながら管理をしていると、自分は何でもできるんだと思って当たり前に感じることかもしれないですが、実はそうでもありません。このあたりの、Azure Storage Account の権限周りを再考していて、わかりづらいところがあったので簡単にまとめておきます。

コントロールプレーン操作とデータプレーン操作

そもそも Azure 含めクラウドサービス上における操作は、コントロールプレーンとデータプレーンという2種類のカテゴリに分けることが可能です。コントロール=制御なので、コントロールプレーン操作はサブスクリプション内のリソースを管理するために使用します。データプレーン操作はリソースインスタンスによって提供される機能の利用に使用します。たとえば、

コントロール プレーンを使って Azure Cosmos DB データベースを作成します。 Azure Cosmos DB データベースのデータに対してクエリを実行するには、データ プレーンを使います。

これらはそれぞれの操作において利用するエンドポイントの違いにも現れており、コントロールプレーン操作は Azure Resource Manager のエンドポイント(https://management.azure.com)に送信されるのに対し、データプレーン操作はインスタンス固有のエンドポイントに対して送信されます。(*1)

これらの操作の違いは、RBAC ロール定義上における ActionsDataActions といった違いとして現れてきます。

ストレージアカウントのアクセス権を考える

例えばタイトルのように BLOB の管理をしたいと思った場合、これはデータプレーンの操作になるため、DataAction を必要とします。しかし、改めて[共同作成者]ロールを見てみると、以下のようにdataActionsは何も入っていません。

{
    "id": "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c",
    "properties": {
        "roleName": "Contributor",
        "description": "Grants full access to manage all resources, but does not allow you to assign roles in Azure RBAC, manage assignments in Azure Blueprints, or share image galleries.",
        "assignableScopes": [
            "/"
        ],
        "permissions": [
            {
                "actions": [
                    "*"
                ],
                "notActions": [
                    "Microsoft.Authorization/*/Delete",
                    "Microsoft.Authorization/*/Write",
                    "Microsoft.Authorization/elevateAccess/Action",
                    "Microsoft.Blueprint/blueprintAssignments/write",
                    "Microsoft.Blueprint/blueprintAssignments/delete",
                    "Microsoft.Compute/galleries/share/action",
                    "Microsoft.Purview/consents/write",
                    "Microsoft.Purview/consents/delete"
                ],
                "dataActions": [],
                "notDataActions": []
            }
        ]
    }
}

一方で、BLOB の管理をしたいとなった場合に本来付けられるであろう[ストレージBLOB共同作成者]のロール定義は以下のようになっています。dataActionsの部分に、BLOB に対する操作のアクションが存在します。

{
    "id": "/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe",
    "properties": {
        "roleName": "Storage Blob Data Contributor",
        "description": "Allows for read, write and delete access to Azure Storage blob containers and data",
        "assignableScopes": [
            "/"
        ],
        "permissions": [
            {
                "actions": [
                    "Microsoft.Storage/storageAccounts/blobServices/containers/delete",
                    "Microsoft.Storage/storageAccounts/blobServices/containers/read",
                    "Microsoft.Storage/storageAccounts/blobServices/containers/write",
                    "Microsoft.Storage/storageAccounts/blobServices/generateUserDelegationKey/action"
                ],
                "notActions": [],
                "dataActions": [
                    "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete",
                    "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read",
                    "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write",
                    "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/move/action",
                    "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/add/action"
                ],
                "notDataActions": []
            }
        ]
    }
}

本来であれば、Microsoft.Storage/storageAccounts/blobServices/containers/blobs/readMicrosoft.Storage/storageAccounts/blobServices/containers/blobs/writeの権限を必要とする操作が[共同作成者]のみでなぜできてしまうのでしょうか。それは、ストレージアカウントの認証方法の違いに起因しています。実際のリソースで見てみます。

挙動の確認のイメージもかねてリソースを見ていく

自分に対して[共同作成者]が付与されたストレージアカウントを用意します。

よく見ると、Azure Portal におけるデフォルトの認証方式はキーによる認証になっています(*2)。キーによる認証は、Microsoft.Storage/storageAccounts/listKeys/actionをもっていればパスすることが可能です(3)。このアクションはactionsに属するため、共同作成者のによって内包されています。つまるところ、これは実際には Microsoft Entra ID のプリンシパルのデータに対するアクセス権を見ているというよりは、ストレージアカウントのアクセスキーを取得できるか?という観点でのフィルターになっています。

よっての認証方法を、Microsoft Entra user accountに変更してみると、DataActions でそのプリンシパルにおける直接の権限を評価した際に、権限が足りずにエラーになります。

明示的に[ストレージBLOBデータ閲覧者]を割り当てて再度アクセスしてみます。

アクセスできるようになっています。

Azure Portal からのアクセスではない場合は?

例えば Azure CLI では以下のようなかたちで BLOB にアクセスできますが、こちらも --auth-mode の指定がない場合はアクセスキー認証になるため、[共同作成者]のようなロールでもアクセス可能となります。Microsoft Entra ID 認証をするには --auth-mode login を指定します(*4)。

az storage blob list --account-name <storageAccountName> \
--container-name <continerName> \
--auth-mode login \

権限がない場合配下のようになります。組み込みロールのアサインもしくは --auth-mode key の利用を示唆されます。

$ az storage blob list --account-name <storageAccountName> --container-name <containerName> --auth-mode login

You do not have the required permissions needed to perform this operation.
Depending on your operation, you may need to be assigned one of the following roles:
    "Storage Blob Data Owner"
    "Storage Blob Data Contributor"
    "Storage Blob Data Reader"
    "Storage Queue Data Contributor"
    "Storage Queue Data Reader"
    "Storage Table Data Contributor"
    "Storage Table Data Reader"

If you want to use the old authentication method and allow querying for the right account key, please use the "--auth-mode" parameter and "key" value.

まとめ

  • [ストレージBLOBデータ閲覧者]権限( DataAction でいえばMicrosoft.Storage/storageAccounts/blobServices/containers/blobs/read)がなくても、共同作成者などの強いロールにはMicrosoft.Storage/storageAccounts/listKeys/actionのアクションが含まれているため、アクセスキー経由で BLOB にアクセスできます。

  • キーにアクセスできる=”そのストレージアカウントへのアクセス権限がある”なので別に問題はないのですが、誤解を生みそうなのでここに記しておきます。

Reference

GitHubで編集を提案
Microsoft (有志)

Discussion