Tutorial: Add a role assignment condition to restrict access to blobs using Azure PowerShell
In most cases, a role assignment grants the permissions you need to Azure resources. However, in some cases you might want to provide more granular access control by adding a role assignment condition.
In this tutorial, you learn how to:
- Add a condition to a role assignment
- Restrict access to blobs based on a blob index tag
Important
Azure attribute-based access control (Azure ABAC) is generally available (GA) for controlling access to Azure Blob Storage, Azure Data Lake Storage Gen2, and Azure Queues using request
, resource
, environment
, and principal
attributes in both the standard and premium storage account performance tiers. Currently, the container metadata resource attribute and the list blob include request attribute are in PREVIEW. For complete feature status information of ABAC for Azure Storage, see Status of condition features in Azure Storage.
See the Supplemental Terms of Use for Microsoft Azure Previews for legal terms that apply to Azure features that are in beta, preview, or otherwise not yet released into general availability.
Prerequisites
For information about the prerequisites to add or edit role assignment conditions, see Conditions prerequisites.
Condition
In this tutorial, you restrict access to blobs with a specific tag. For example, you add a condition to a role assignment so that Chandra can only read files with the tag Project=Cascade.
If Chandra tries to read a blob without the tag Project=Cascade, access isn't allowed.
Here's what the condition looks like in code:
(
(
!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'}
AND NOT
SubOperationMatches{'Blob.List'})
)
OR
(
@Resource[Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags:Project<$key_case_sensitive$>] StringEquals 'Cascade'
)
)
Step 1: Install prerequisites
Open a PowerShell window.
Use Get-InstalledModule to check versions of installed modules.
Get-InstalledModule -Name Az Get-InstalledModule -Name Az.Resources Get-InstalledModule -Name Az.Storage
If necessary, use Install-Module to install the required versions for the Az, Az.Resources, and Az.Storage modules.
Install-Module -Name Az -RequiredVersion 5.5.0 Install-Module -Name Az.Resources -RequiredVersion 3.2.1 Install-Module -Name Az.Storage -RequiredVersion 2.5.2-preview -AllowPrerelease
Close and reopen PowerShell to refresh session.
Step 2: Sign in to Azure
Use the Connect-AzAccount command and follow the instructions that appear to sign in to your directory as User Access Administrator or Owner.
Connect-AzAccount
Use Get-AzSubscription to list all of your subscriptions.
Get-AzSubscription
Determine the subscription ID and initialize the variable.
$subscriptionId = "<subscriptionId>"
Set the subscription as the active subscription.
$context = Get-AzSubscription -SubscriptionId $subscriptionId Set-AzContext $context
Step 3: Create a user
Use New-MgUser to create a user or find an existing user. This tutorial uses Chandra as the example.
Initialize the variable for the object ID of the user.
$userObjectId = "<userObjectId>"
Step 4: Set up storage
Use New-AzStorageAccount to create a storage account that is compatible with the blob index feature. For more information, see Manage and find Azure Blob data with blob index tags.
Use New-AzStorageContainer to create a new blob container within the storage account and set the anonymous access level to Private (no anonymous access).
Use Set-AzStorageBlobContent to upload a text file to the container.
Add the following blob index tag to the text file. For more information, see Use blob index tags to manage and find data on Azure Blob Storage.
Note
Blobs also support the ability to store arbitrary user-defined key-value metadata. Although metadata is similar to blob index tags, you must use blob index tags with conditions.
Key Value Project Cascade Upload a second text file to the container.
Add the following blob index tag to the second text file.
Key Value Project Baker Initialize the following variables with the names you used.
$resourceGroup = "<resourceGroup>" $storageAccountName = "<storageAccountName>" $containerName = "<containerName>" $blobNameCascade = "<blobNameCascade>" $blobNameBaker = "<blobNameBaker>"
Step 5: Assign a role with a condition
Initialize the Storage Blob Data Reader role variables.
$roleDefinitionName = "Storage Blob Data Reader" $roleDefinitionId = "2a2b9908-6ea1-4ae2-8e65-a410df84e7d1"
Initialize the scope for the resource group.
$scope = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup"
Initialize the condition.
$condition = "((!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'} AND NOT SubOperationMatches{'Blob.List'})) OR (@Resource[Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags:Project<`$key_case_sensitive`$>] StringEquals 'Cascade'))"
In PowerShell, if your condition includes a dollar sign ($), you must prefix it with a backtick (`). For example, this condition uses dollar signs to delineate the tag key name.
Initialize the condition version and description.
$conditionVersion = "2.0" $description = "Read access to blobs with the tag Project=Cascade"
Use New-AzRoleAssignment to assign the Storage Blob Data Reader role with a condition to the user at a resource group scope.
New-AzRoleAssignment -ObjectId $userObjectId -Scope $scope -RoleDefinitionId $roleDefinitionId -Description $description -Condition $condition -ConditionVersion $conditionVersion
Here's an example of the output:
RoleAssignmentId : /subscriptions/<subscriptionId>/resourceGroups/<resourceGroup>/providers/Microso ft.Authorization/roleAssignments/<roleAssignmentId> Scope : /subscriptions/<subscriptionId>/resourceGroups/<resourceGroup> DisplayName : Chandra SignInName : [email protected] RoleDefinitionName : Storage Blob Data Reader RoleDefinitionId : 2a2b9908-6ea1-4ae2-8e65-a410df84e7d1 ObjectId : <userObjectId> ObjectType : User CanDelegate : False Description : Read access to blobs with the tag Project=Cascade ConditionVersion : 2.0 Condition : ((!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'} AND NOT SubOperationMatches{'Blob.List'})) OR (@Resource[Microsoft.Storage/storageAccounts/blobServices/co ntainers/blobs/tags:Project<$key_case_sensitive$>] StringEquals 'Cascade'))
Step 6: (Optional) View the condition in the Azure portal
In the Azure portal, open the resource group.
Select Access control (IAM).
On the Role assignments tab, find the role assignment.
In the Condition column, select View/Edit to view the condition.
Step 7: Test the condition
Open a new PowerShell window.
Use Connect-AzAccount to sign in as Chandra.
Connect-AzAccount
Initialize the following variables with the names you used.
$storageAccountName = "<storageAccountName>" $containerName = "<containerName>" $blobNameBaker = "<blobNameBaker>" $blobNameCascade = "<blobNameCascade>"
Use New-AzStorageContext to create a specific context to access your storage account more easily.
$bearerCtx = New-AzStorageContext -StorageAccountName $storageAccountName
Use Get-AzStorageBlob to try to read the file for the Baker project.
Get-AzStorageBlob -Container $containerName -Blob $blobNameBaker -Context $bearerCtx
Here's an example of the output. Notice that you can't read the file because of the condition you added.
Get-AzStorageBlob : This request is not authorized to perform this operation using this permission. HTTP Status Code: 403 - HTTP Error Message: This request is not authorized to perform this operation using this permission. ErrorCode: AuthorizationPermissionMismatch ErrorMessage: This request is not authorized to perform this operation using this permission. RequestId: <requestId> Time: Sat, 24 Apr 2021 13:26:25 GMT At line:1 char:1 + Get-AzStorageBlob -Container $containerName -Blob $blobNameBaker -Con ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : CloseError: (:) [Get-AzStorageBlob], StorageException + FullyQualifiedErrorId : StorageException,Microsoft.WindowsAzure.Commands.Storage.Blob.Cmdlet.GetAzureStorageBlob Command
Read the file for the Cascade project.
Get-AzStorageBlob -Container $containerName -Blob $blobNameCascade -Context $bearerCtx
Here's an example of the output. Notice that you can read the file because it has the tag Project=Cascade.
AccountName: <storageAccountName>, ContainerName: <containerName> Name BlobType Length ContentType LastModified AccessTier SnapshotT ime ---- -------- ------ ----------- ------------ ---------- --------- CascadeFile.txt BlockBlob 7 text/plain 2021-04-24 05:35:24Z Hot
Step 8: (Optional) Edit the condition
In the other PowerShell window, use Get-AzRoleAssignment to get the role assignment you added.
$testRa = Get-AzRoleAssignment -Scope $scope -RoleDefinitionName $roleDefinitionName -ObjectId $userObjectId
Edit the condition.
$condition = "((!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'} AND NOT SubOperationMatches{'Blob.List'})) OR (@Resource[Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags:Project<`$key_case_sensitive`$>] StringEquals 'Cascade' OR @Resource[Microsoft.Storage/storageAccounts/blobServices/containers/blobs/tags:Project<`$key_case_sensitive`$>] StringEquals 'Baker'))"
Initialize the condition and description.
$testRa.Condition = $condition $testRa.Description = "Read access to blobs with the tag Project=Cascade or Project=Baker"
Use Set-AzRoleAssignment to update the condition for the role assignment.
Set-AzRoleAssignment -InputObject $testRa -PassThru
Here's an example of the output:
RoleAssignmentId : /subscriptions/<subscriptionId>/resourceGroups/<resourceGroup>/providers/Microso ft.Authorization/roleAssignments/<roleAssignmentId> Scope : /subscriptions/<subscriptionId>/resourceGroups/<resourceGroup> DisplayName : Chandra SignInName : [email protected] RoleDefinitionName : Storage Blob Data Reader RoleDefinitionId : 2a2b9908-6ea1-4ae2-8e65-a410df84e7d1 ObjectId : <userObjectId> ObjectType : User CanDelegate : False Description : Read access to blobs with the tag Project=Cascade or Project=Baker ConditionVersion : 2.0 Condition : ((!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'} AND NOT SubOperationMatches{'Blob.List'})) OR (@Resource[Microsoft.Storage/storageAccounts/blobServices/co ntainers/blobs/tags:Project<$key_case_sensitive$>] StringEquals 'Cascade' OR @Resource[Microsoft.S torage/storageAccounts/blobServices/containers/blobs/tags:Project<$key_case_sensitive$>] StringEquals 'Baker'))
Step 9: Clean up resources
Use Remove-AzRoleAssignment to remove the role assignment and condition you added.
Remove-AzRoleAssignment -ObjectId $userObjectId -RoleDefinitionName $roleDefinitionName -ResourceGroupName $resourceGroup
Delete the storage account you created.
Delete the user you created.