Adding access policy for storage container with Python

Denis Mukhamedov 20 Reputation points
2024-05-07T15:54:09.2933333+00:00

I'm trying to write a python script to add access policy to container. The initial code works, but it's deleting all current policies and create a new one.

from azure.storage.blob import BlobServiceClient, ContainerSasPermissions, AccessPolicy
from datetime import datetime, timedelta

storageAccountName = 'azure_account'
storageAccountKey = 'azure_key'
containerName = 'azure_container'

storageUrl = f'https://{storageAccountName}.blob.core.windows.net'
storageServiceClient = BlobServiceClient(account_url=storageUrl, credential=storageAccountKey)
containerServiceClient = storageServiceClient.get_container_client(containerName)

accessPolicySettings = AccessPolicy(permission=ContainerSasPermissions(read=True),
                                    expiry=datetime.utcnow() + timedelta(hours=24),
                                    start=datetime.utcnow() - timedelta(minutes=1))
identifiers = {'new_policy': accessPolicySettings}
containerServiceClient.set_container_access_policy(signed_identifiers=identifiers)

get_container_access_policy method seems to get current policies, but I'm struggling to add new one.

Thank you in advance for your assistance.

from azure.storage.blob import BlobServiceClient, ContainerSasPermissions, AccessPolicy
from datetime import datetime, timedelta

storageAccountName = 'azure_account'
storageAccountKey = 'azure_key'
containerName = 'azure_container'

storageUrl = f'https://{storageAccountName}.blob.core.windows.net'
storageServiceClient = BlobServiceClient(account_url=storageUrl, credential=storageAccountKey)
containerServiceClient = storageServiceClient.get_container_client(containerName)

containerAcl = containerServiceClient.get_container_access_policy()
accessPolicySettings = AccessPolicy(permission=ContainerSasPermissions(read=True),
                                    expiry=datetime.utcnow() + timedelta(hours=24),
                                    start=datetime.utcnow() - timedelta(minutes=1))
containerAcl['new_policy'] = [accessPolicySettings]
containerServiceClient.set_container_access_policy(signed_identifiers=containerAcl.get('signed_identifiers', {}))

Traceback (most recent call last):
  File "C:\Python\test.py", line 17, in 
Azure Blob Storage
Azure Blob Storage
An Azure service that stores unstructured data in the cloud as blobs.
2,509 questions
0 comments No comments
{count} votes

4 answers

Sort by: Most helpful
  1. Anand Prakash Yadav 6,940 Reputation points Microsoft Vendor
    2024-05-08T10:12:33.7366667+00:00

    Hello Denis Mukhamedov,

    Thank you for posting your query here!

    Can you please try with the following code to add a new access policy to an Azure Blob Storage container without deleting existing policies:

    from azure.storage.blob import BlobServiceClient, ContainerSasPermissions, AccessPolicy
    from datetime import datetime, timedelta
    
    # Initialize the BlobServiceClient
    storageAccountName = 'azure_account'
    storageAccountKey = 'azure_key'
    containerName = 'azure_container'
    storageUrl = f'https://{storageAccountName}.blob.core.windows.net'
    storageServiceClient = BlobServiceClient(account_url=storageUrl, credential=storageAccountKey)
    
    # Get the existing access policies
    containerServiceClient = storageServiceClient.get_container_client(containerName)
    existing_policies = containerServiceClient.get_container_access_policy()
    
    # Check if the 'signed_identifiers' field exists, create it if it doesn't
    if 'signed_identifiers' not in existing_policies:
        existing_policies['signed_identifiers'] = {}
    
    # Define your new access policy
    new_policy = AccessPolicy(permission=ContainerSasPermissions(read=True),
                              expiry=datetime.utcnow() + timedelta(hours=24),
                              start=datetime.utcnow() - timedelta(minutes=1))
    
    # Add the new policy to the existing ones
    existing_policies['signed_identifiers']['new_policy'] = new_policy
    
    # Update the container with the full set of policies
    containerServiceClient.set_container_access_policy(signed_identifiers=existing_policies['signed_identifiers'])
    
    
    

    Do let us know if you have any further queries. I’m happy to assist you further.


  2. Rahul Gosavi 0 Reputation points
    2024-05-08T12:22:06.69+00:00

    Try with below code

    from azure.storage.blob import BlobServiceClient, ContainerSasPermissions, AccessPolicy

    from datetime import datetime, timedelta

    storageAccountName = 'azure_account'

    storageAccountKey = 'azure_key'

    containerName = 'azure_container'

    storageUrl = f'https://{storageAccountName}.blob.core.windows.net'

    storageServiceClient = BlobServiceClient(account_url=storageUrl, credential=storageAccountKey)

    containerServiceClient = storageServiceClient.get_container_client(containerName)

    # Retrieve existing access policies

    policies = containerServiceClient.get_container_access_policy()

    # If there are existing policies, keep them; otherwise, create an empty dictionary

    identifiers = policies if policies else {}

    # Add or update the new access policy

    accessPolicySettings = AccessPolicy(permission=ContainerSasPermissions(read=True),

    expiry=datetime.utcnow() + timedelta(hours=24),

    start=datetime.utcnow() - timedelta(minutes=1))

    identifiers['new_policy'] = accessPolicySettings

    # Set the updated access policies to the container

    containerServiceClient.set_container_access_policy(signed_identifiers=identifiers)


  3. Denis Mukhamedov 20 Reputation points
    2024-05-17T16:38:43.7+00:00

    Found the solution

    from azure.storage.blob import BlobServiceClient, ContainerSasPermissions, AccessPolicy
    import datetime
    
    # Replace with your Azure Storage account details
    account_name = 'your_account_name'
    account_key = 'your_account_key'
    container_name = 'your_container_name'
    policy_id = 'your_policy_id'  # The ID for the new policy
    policy_start = datetime.datetime.utcnow()
    policy_expiry = policy_start + datetime.timedelta(hours=1)  # Example: 1 hour validity
    
    # Initialize the BlobServiceClient
    blob_service_client = BlobServiceClient(account_url=f"https://{account_name}.blob.core.windows.net", credential=account_key)
    
    # Get the container client
    container_client = blob_service_client.get_container_client(container_name)
    
    # Define the new access policy
    new_access_policy = AccessPolicy(permission=ContainerSasPermissions(read=True, write=True), start=policy_start, expiry=policy_expiry)
    
    # Get the existing access policies
    existing_policies = container_client.get_container_access_policy()['signed_identifiers']
    
    # Convert the list of existing policies to a dictionary
    existing_policies_dict = {policy.id: policy.access_policy for policy in existing_policies}
    
    # Update the existing policies with the new one
    existing_policies_dict[policy_id] = new_access_policy
    
    # Set the updated policies back to the container
    container_client.set_container_access_policy(signed_identifiers=existing_policies_dict)
    
    
    0 comments No comments

  4. Anand Prakash Yadav 6,940 Reputation points Microsoft Vendor
    2024-05-20T11:42:20.25+00:00

    Hi Denis Mukhamedov, I'm glad that you were able to resolve your issue and thank you for posting your solution so that others experiencing the same thing can easily reference this!

    Since the Microsoft Q&A community has a policy that "The question author cannot accept their own answer. They can only accept answers by others ", I'll repost your solution in case you'd like to "Accept" the answer. Accepted answers show up at the top, resulting in improved discoverability for others.

    Issue: The initial code deletes all existing access policies for the storage container and creates a new one instead of adding a new policy while retaining the existing ones. The attempted solution encounters an error when trying to add a new policy directly to the existing policies dictionary returned by get_container_access_policy().

    Root Cause: The initial code deletes existing access policies before adding a new one, causing the loss of previously configured policies. The attempted solution doesn't handle existing policies correctly when adding a new one, leading to errors in directly modifying the existing policies dictionary.

    Solution:  Customer provided solution that fixed the issue.

    from azure.storage.blob import BlobServiceClient, ContainerSasPermissions, AccessPolicy
    import datetime
    
    # Replace with your Azure Storage account details
    account_name = 'your_account_name'
    account_key = 'your_account_key'
    container_name = 'your_container_name'
    policy_id = 'your_policy_id'  # The ID for the new policy
    policy_start = datetime.datetime.utcnow()
    policy_expiry = policy_start + datetime.timedelta(hours=1)  # Example: 1 hour validity
    
    # Initialize the BlobServiceClient
    blob_service_client = BlobServiceClient(account_url=f"https://{account_name}.blob.core.windows.net", credential=account_key)
    
    # Get the container client
    container_client = blob_service_client.get_container_client(container_name)
    
    # Define the new access policy
    new_access_policy = AccessPolicy(permission=ContainerSasPermissions(read=True, write=True), start=policy_start, expiry=policy_expiry)
    
    # Get the existing access policies
    existing_policies = container_client.get_container_access_policy()['signed_identifiers']
    
    # Convert the list of existing policies to a dictionary
    existing_policies_dict = {policy.id: policy.access_policy for policy in existing_policies}
    
    # Update the existing policies with the new one
    existing_policies_dict[policy_id] = new_access_policy
    
    # Set the updated policies back to the container
    container_client.set_container_access_policy(signed_identifiers=existing_policies_dict)
    
    
    0 comments No comments