Managing Access to Azure Blob Storage with Python
This document provides a comprehensive guide on how to manage access to Azure Blob Storage using the Python SDK. You'll learn about different access control mechanisms, including Shared Access Signatures (SAS), Access Control Lists (ACLs), and Role-Based Access Control (RBAC).
1. Understanding Access Control Mechanisms
Azure Storage offers several ways to control access to your data:
- Shared Access Signatures (SAS): Provide granular access to blobs or containers for a specific period, with specific permissions (read, write, delete, list).
- Access Control Lists (ACLs): Used for managing access to individual blobs and containers, especially when using Azure Active Directory (Azure AD) identities.
- Role-Based Access Control (RBAC): Assign built-in or custom roles to users, groups, or service principals to grant permissions at different scopes (storage account, container).
2. Using Shared Access Signatures (SAS) with Python
SAS tokens allow you to delegate limited authority to clients without sharing your account keys. You can generate SAS tokens for containers or individual blobs.
Generating a Service SAS for a Container:
A service SAS is signed with the storage account key.
from azure.storage.blob import BlobServiceClient, generate_container_sas, ContainerSasPermissions
from datetime import datetime, timedelta
# Replace with your actual connection string
connection_string = "YOUR_AZURE_STORAGE_CONNECTION_STRING"
container_name = "my-container"
# Get the blob service client
blob_service_client = BlobServiceClient.from_connection_string(connection_string)
container_client = blob_service_client.get_container_client(container_name)
# Define permissions and expiry
# Permissions: read, write, delete, list
permissions = ContainerSasPermissions(read=True, write=True, list=True)
expiry_time = datetime.utcnow() + timedelta(hours=1)
# Generate the SAS token
sas_token = generate_container_sas(
account_name=blob_service_client.account_name,
account_key=blob_service_client.credential.account_key, # Access account key from client
container_name=container_name,
permission=permissions,
expiry=expiry_time
)
print(f"Generated SAS Token: {sas_token}")
Generating a User Delegation SAS for a Container:
A user delegation SAS is signed with Azure AD credentials.
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient, generate_container_sas, ContainerSasPermissions
from datetime import datetime, timedelta
# Replace with your actual storage account name
account_url = "https://myaccount.blob.core.windows.net"
container_name = "my-container"
# Authenticate using Azure AD
credential = DefaultAzureCredential()
blob_service_client = BlobServiceClient(account_url=account_url, credential=credential)
container_client = blob_service_client.get_container_client(container_name)
# Define permissions and expiry
permissions = ContainerSasPermissions(read=True, write=True)
expiry_time = datetime.utcnow() + timedelta(days=1)
# Generate the SAS token
sas_token = generate_container_sas(
account_name=blob_service_client.account_name,
credential=credential, # Use Azure AD credential for signing
container_name=container_name,
permission=permissions,
expiry=expiry_time
)
print(f"Generated User Delegation SAS Token: {sas_token}")
Generating a Blob SAS:
You can generate SAS for individual blobs with similar options.
from azure.storage.blob import BlobClient, generate_blob_sas, BlobSasPermissions
from datetime import datetime, timedelta
connection_string = "YOUR_AZURE_STORAGE_CONNECTION_STRING"
container_name = "my-container"
blob_name = "my-blob.txt"
blob_client = BlobClient.from_connection_string(connection_string, container_name, blob_name)
permissions = BlobSasPermissions(read=True)
expiry_time = datetime.utcnow() + timedelta(minutes=30)
sas_token = generate_blob_sas(
account_name=blob_client.account_name,
account_key=blob_client.credential.account_key,
container_name=container_name,
blob_name=blob_name,
permission=permissions,
expiry=expiry_time
)
print(f"Generated Blob SAS Token: {sas_token}")
3. Managing Access with Azure AD and RBAC
For more robust and integrated security, leverage Azure Active Directory (Azure AD) with Role-Based Access Control (RBAC).
Assigning Roles using Python:
You can use the Azure management libraries to assign roles.
from azure.identity import DefaultAzureCredential
from azure.mgmt.storage import StorageManagementClient
from azure.mgmt.storage.models import RoleAssignment, RoleDefinition
# Replace with your subscription ID, resource group name, and storage account name
subscription_id = "YOUR_SUBSCRIPTION_ID"
resource_group_name = "YOUR_RESOURCE_GROUP_NAME"
storage_account_name = "YOUR_STORAGE_ACCOUNT_NAME"
principal_id = "ID_OF_USER_OR_SERVICE_PRINCIPAL" # e.g., a user's object ID
credential = DefaultAzureCredential()
storage_client = StorageManagementClient(credential, subscription_id)
# Example: Assign "Storage Blob Data Reader" role to a principal
role_definition_id = f"/subscriptions/{subscription_id}/providers/Microsoft.Authorization/roleDefinitions/2a2b9841-075f-4d7d-8751-268ed3c7c337" # Role ID for Storage Blob Data Reader
role_assignment_params = RoleAssignment(
principal_id=principal_id,
role_definition_id=role_definition_id,
scope=f"/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.Storage/storageAccounts/{storage_account_name}"
)
storage_client.role_assignments.create(
scope=role_assignment_params.scope,
role_assignment_name=f"assignment-{principal_id}-{role_definition_id.split('/')[-1]}", # Unique name for assignment
parameters=role_assignment_params
)
print(f"Role assignment created for principal {principal_id}.")
4. Setting Public Access Level for Containers
You can make containers and their blobs publicly accessible, or restrict access to anonymous users.
from azure.storage.blob import BlobServiceClient, PublicAccess
connection_string = "YOUR_AZURE_STORAGE_CONNECTION_STRING"
container_name = "my-public-container"
blob_service_client = BlobServiceClient.from_connection_string(connection_string)
container_client = blob_service_client.get_container_client(container_name)
# Set public access level to Blob (anonymous read access for blobs only)
# Options: PublicAccess.OFF, PublicAccess.Blob, PublicAccess.Container
container_client.set_container_access_policy(public_access=PublicAccess.Blob)
print(f"Public access set to Blob for container '{container_name}'.")
Important Note on Security:
Always follow the principle of least privilege. Grant only the necessary permissions to users and applications. Prefer Azure AD authentication and RBAC over SAS tokens for long-lived access. Use SAS tokens judiciously for temporary or delegated access.
Tip:
When generating SAS tokens programmatically, ensure your application handles the storage account key securely. Consider using Azure Key Vault to store sensitive credentials.
Conclusion
Managing access effectively is crucial for securing your data in Azure Blob Storage. By understanding and implementing SAS, ACLs, and RBAC with the Azure SDK for Python, you can build secure and robust applications.