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... 🙄

5
  • 1
    You would need to assign appropriate storage data related permissions e.g. blob data reader. Please retry after assigning appropriate data role. Commented Jun 23, 2021 at 2:11
  • Thanks Gaurav, Do you mean that the user calling get_user_delegation_key needs more permissions than those included in the Contributor role? Commented Jun 23, 2021 at 2: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 - learn.microsoft.com/en-us/azure/storage/blobs/…. Commented Jun 23, 2021 at 2:18
  • 1
    Gaurav's answer is correct. Once I got "Storage Blob Data Contributor" the above code worked without a hitch. Thanks! Commented Jun 24, 2021 at 6:02
  • Awesome. Let me post my comment as an answer. Commented Jun 24, 2021 at 6:04

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.