2

I'm trying to generate SAS URLs to read blobs using a user delegation key and the Azure SDK for Python.

The following code works if I use the storage account key but fails if I try to use the user delegation key.

import datetime as dt
import json
import os
from azure.identity import DefaultAzureCredential
from azure.storage.blob import (
    BlobClient,
    BlobSasPermissions,
    BlobServiceClient,
    generate_blob_sas,
)

credential = DefaultAzureCredential(exclude_shared_token_cache_credential=True)
    
storage_acct_name = "XYZ_storage_account"
container_name = "XYZ_blob_container"
blob_name = "xyz_data.json"

url = f"https://{storage_acct_name}.blob.core.windows.net"
blob_service_client = BlobServiceClient(url, credential=credential)
udk = blob_service_client.get_user_delegation_key(
    key_start_time=dt.datetime.utcnow() - dt.timedelta(hours=1),
    key_expiry_time=dt.datetime.utcnow() + dt.timedelta(hours=1))

sas = generate_blob_sas(
    account_name=storage_acct_name,
    container_name=container_name,
    blob_name=blob_name,
    user_delegation_key=udk,
    #account_key=os.getenv("STORAGE_ACCOUNT_ACCESS_KEY"),
    permission=BlobSasPermissions(read=True),
    start = dt.datetime.utcnow() - dt.timedelta(minutes=15),
    expiry = dt.datetime.utcnow() + dt.timedelta(hours=2),
)

sas_url = (
    f'https://{storage_acct_name}.blob.core.windows.net/'
    f'{container_name}/{blob_name}?{sas}'
)

blob_client = BlobClient.from_blob_url(sas_url)
blob_data = blob_client.download_blob(encoding='UTF-8')
data = json.loads(blob_data.readall())

Using the UDK, I get the following error:

“This request is not authorized to perform this operation using this permission. ... ErrorCode:AuthorizationPermissionMismatch”

Having the storage account key floating around is non-ideal for security, so I'd much rather use the UDK.

In the Azure portal, I can view storage account | Access Control (IAM) | View My Access and see that I have role “Contributor”, scope “Subscription (Inherited)”.

It looks like from the docs that “Contributor” should give the require “generateUserDelegationKey” permission, but...

cbare
  • 12,060
  • 8
  • 56
  • 63
  • 1
    You would need to assign appropriate storage data related permissions e.g. blob data reader. Please retry after assigning appropriate data role. – Gaurav Mantri Jun 23 '21 at 02:11
  • Thanks Gaurav, Do you mean that the user calling _get_user_delegation_key_ needs more permissions than those included in the Contributor role? – cbare Jun 23 '21 at 02:16
  • 1
    Yes. "Contributor" role is a control plane RBAC role i.e. it is used for managing the storage account. To manage data inside a storage account, you would need to assign data related RBAC role - https://learn.microsoft.com/en-us/azure/storage/blobs/assign-azure-role-data-access?tabs=portal. – Gaurav Mantri Jun 23 '21 at 02:18
  • 1
    Gaurav's answer is correct. Once I got "Storage Blob Data Contributor" the above code worked without a hitch. Thanks! – cbare Jun 24 '21 at 06:02
  • Awesome. Let me post my comment as an answer. – Gaurav Mantri Jun 24 '21 at 06:04

1 Answers1

1

As mentioned in the comments, in order for a SAS token obtained via user delegation key, the user should have appropriate data related RBAC role for the storage account.

The reason you got this error is because the user is assigned a Contributor role which is a control plane RBAC role. Control plane RBAC roles are meant to manage the resources (like storage accounts themselves) and not the data inside them. For managing data, a user must be assigned appropriate data RBAC role.

More information about these roles can be found here: https://learn.microsoft.com/en-us/azure/storage/blobs/assign-azure-role-data-access?tabs=portal.

Gaurav Mantri
  • 128,066
  • 12
  • 206
  • 241