Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Note
Azure ABAC for Key Vault is in preview. Some aspects might change before general availability. For preview terms, see the supplemental terms of use.
In most cases, an Azure role assignment grants the permissions you need to Azure resources. In some cases, you might want more granular access control by adding a role assignment condition.
This article shows how to use Azure PowerShell to add an Azure attribute-based access control (Azure ABAC) condition to a Key Vault role assignment so that a principal can only read secrets whose names start with a specific prefix.
For the full set of supported actions and attributes, see Actions and attributes for Azure Key Vault ABAC conditions (preview).
Important
ABAC conditions only work when the key vault's permission model is set to Azure role-based access control. Legacy vault access policies don't support conditions.
Prerequisites
- For information about the prerequisites to add or edit role assignment conditions, see Conditions prerequisites.
- The target key vault must have its permission model set to Azure role-based access control.
- Azure PowerShell installed locally, or use Azure Cloud Shell.
Condition
In this article, you restrict access to secrets whose names begin with test-app. If the user tries to read a secret without the test-app name prefix, access isn't allowed.
Here's what the condition looks like:
(
(
!(ActionMatches{'Microsoft.KeyVault/vaults/secrets/getSecret/action'})
)
OR
(
@Resource[Microsoft.KeyVault/vaults/secrets:name] StringStartsWith 'test-app'
)
)
Step 1: Install prerequisites
Open a PowerShell window.
Use Get-InstalledModule to check the versions of installed modules.
Get-InstalledModule -Name Az Get-InstalledModule -Name Az.Resources Get-InstalledModule -Name Az.KeyVault Get-InstalledModule -Name Microsoft.Graph.UsersIf necessary, use Install-Module to install the required versions of the
Az,Az.Resources, andAz.KeyVaultmodules. You only need theMicrosoft.Graph.Usersmodule if you plan to create a new user withNew-MgUserin Step 3; you can skip it if you reuse an existing user.Install-Module -Name Az Install-Module -Name Az.Resources Install-Module -Name Az.KeyVault Install-Module -Name Microsoft.Graph.UsersClose and reopen PowerShell to refresh the session.
Step 2: Sign in to Azure
Use Connect-AzAccount and follow the instructions to sign in as a User Access Administrator or Owner.
Connect-AzAccountUse Get-AzSubscription to list your subscriptions. Format the output as a list so the full subscription IDs aren't truncated.
Get-AzSubscription | Format-List Name, Id, TenantIdAlternatively, display the results in a table with an untruncated
Idcolumn:Get-AzSubscription | Format-Table Name, Id, State -AutoSizeSet your subscription as the active subscription.
$subscriptionId = "<subscriptionId>" $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 article uses User1 as the example.
Note
New-MgUser belongs to the Microsoft.Graph.Users module (installed in Step 1), not to the Az modules. It also requires a separate Microsoft Graph sign-in from Connect-AzAccount. Before you run it, connect with the User.ReadWrite.All scope:
Connect-MgGraph -Scopes "User.ReadWrite.All"
If you're reusing an existing user, you can skip both the Microsoft.Graph.Users module and Connect-MgGraph and supply that user's object ID.
Initialize a variable with the user's object ID.
$userObjectId = "<userObjectId>"
Step 4: Set up the key vault
Use New-AzKeyVault to create a key vault that uses Azure RBAC as its permission model.
New-AzKeyVault -Name "<keyVaultName>" -ResourceGroupName "<resourceGroup>" -Location "<location>"Note
In
Az.KeyVault6.0.0 and later, Azure RBAC is the default permission model, so you don't need to specify an extra switch. The-EnableRbacAuthorizationswitch was removed in 6.0.0. If you include it, the command now fails withA parameter cannot be found that matches parameter name 'EnableRbacAuthorization'. Use-DisableRbacAuthorizationonly if you explicitly want the legacy vault access policy model instead.If you're running an older
Az.KeyVaultversion (earlier than 6.0.0), RBAC isn't the default, so you must add the-EnableRbacAuthorizationswitch:New-AzKeyVault -Name "<keyVaultName>" -ResourceGroupName "<resourceGroup>" -Location "<location>" -EnableRbacAuthorizationCheck your installed version with
Get-InstalledModule -Name Az.KeyVault.Grant yourself a Key Vault data-plane role so you can create secrets. When a vault uses Azure RBAC (the default), control-plane roles such as Owner or Contributor don't grant access to secret values. Without a data-plane role,
Set-AzKeyVaultSecretfails withOperation returned an invalid status code 'Forbidden'andAssignment: (not found).# Object ID of the signed-in user (use -UserPrincipalName "you@tenant.com" if this returns nothing) $me = (Get-AzADUser -SignedIn).Id # Scope the assignment to the vault you just created $vaultScope = "/subscriptions/$subscriptionId/resourceGroups/<resourceGroup>/providers/Microsoft.KeyVault/vaults/<keyVaultName>" New-AzRoleAssignment -ObjectId $me ` -RoleDefinitionName "Key Vault Secrets Officer" ` -Scope $vaultScopeNote
Use Key Vault Secrets Officer to create and manage secret values, or Key Vault Administrator for full data-plane access. Key Vault Secrets User is read-only. After you assign a role, wait 1–5 minutes for propagation before you run the next command. A
Forbiddenerror immediately after assignment usually means the role hasn't propagated yet.Use Set-AzKeyVaultSecret to create a secret named
test-app-secret1.$secretValue = ConvertTo-SecureString "<secretValue>" -AsPlainText -Force Set-AzKeyVaultSecret -VaultName "<keyVaultName>" -Name "test-app-secret1" -SecretValue $secretValueNote
The secret name is the resource attribute evaluated by the condition. Choose names that reflect the prefix you plan to restrict access to.
Create a second secret named
test-db-password.Set-AzKeyVaultSecret -VaultName "<keyVaultName>" -Name "test-db-password" -SecretValue $secretValueInitialize variables with the names you used.
$resourceGroup = "<resourceGroup>" $keyVaultName = "<keyVaultName>" $secretNameAllowed = "test-app-secret1" $secretNameDenied = "test-db-password"
Step 5: Assign a role with a condition
Initialize the Key Vault Secrets User role variables.
$roleDefinitionName = "Key Vault Secrets User" $roleDefinitionId = "4633458b-17de-408a-b874-0445c86b69e6"Initialize the scope for the resource group. If you didn't set the
$resourceGroupvariable earlier in this session, set it to the name of the resource group that contains your key vault.$resourceGroup = "<resourceGroup>" $scope = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup"Initialize the condition.
$condition = "((!(ActionMatches{'Microsoft.KeyVault/vaults/secrets/getSecret/action'})) OR (@Resource[Microsoft.KeyVault/vaults/secrets:name] StringStartsWith 'test-app'))"Important
The condition must be a single-line string. Multi-line conditions are rejected. If you build the condition in a here-string or across multiple lines, flatten it first:
$condition = $condition -replace '\s+', ' 'In PowerShell, if your condition includes a dollar sign (
$), prefix it with a backtick (`).Initialize the condition version and description.
$conditionVersion = "2.0" $description = "Read access to secrets whose names start with test-app"Use New-AzRoleAssignment to assign the Key Vault Secrets User role with a condition to the user at resource group scope.
New-AzRoleAssignment -ObjectId $userObjectId -Scope $scope -RoleDefinitionId $roleDefinitionId -Description $description -Condition $condition -ConditionVersion $conditionVersionExample output:
RoleAssignmentId : /subscriptions/<subscriptionId>/resourceGroups/<resourceGroup>/providers/Microsoft.Authorization/roleAssignments/<roleAssignmentId> Scope : /subscriptions/<subscriptionId>/resourceGroups/<resourceGroup> DisplayName : User1 SignInName : user1@contoso.com RoleDefinitionName : Key Vault Secrets User RoleDefinitionId : 4633458b-17de-408a-b874-0445c86b69e6 ObjectId : <userObjectId> ObjectType : User CanDelegate : False Description : Read access to secrets whose names start with test-app ConditionVersion : 2.0 Condition : ((!(ActionMatches{'Microsoft.KeyVault/vaults/secrets/getSecret/action'})) OR (@Resource[Microsoft.KeyVault/vaults/secrets:name] StringStartsWith 'test-app'))
Step 6: Test the condition
Open a new PowerShell window.
Use Connect-AzAccount to sign in as User1.
Connect-AzAccountInitialize the variables you used earlier.
$keyVaultName = "<keyVaultName>" $secretNameAllowed = "test-app-secret1" $secretNameDenied = "test-db-password"Use Get-AzKeyVaultSecret to try to read the denied secret.
Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $secretNameDenied -AsPlainTextExample output. Notice that the read fails because of the condition:
Get-AzKeyVaultSecret : Operation returned an invalid status code 'Forbidden' Caller is not authorized to perform action on resource. If role assignments, deny assignments or role definitions changed recently, please observe propagation time. ... ForbiddenByRbacRead the secret whose name starts with
test-app.Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $secretNameAllowed -AsPlainTextYou can read this secret because its name starts with
test-app.
Step 7: (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 | Where-Object { $_.Scope -eq $scope }Important
Get-AzRoleAssignmentalso returns assignments inherited from higher scopes (for example, the same role assigned at the subscription level). If the principal holds this role at more than one scope,$testRabecomes an array, and the next step fails withThe property 'Condition' cannot be found on this object. TheWhere-Object { $_.Scope -eq $scope }filter keeps only the assignment at your resource group scope so$testRais a single object.Edit the condition to also allow secrets whose names start with
api-.$condition = "((!(ActionMatches{'Microsoft.KeyVault/vaults/secrets/getSecret/action'})) OR (@Resource[Microsoft.KeyVault/vaults/secrets:name] StringStartsWith 'test-app' OR @Resource[Microsoft.KeyVault/vaults/secrets:name] StringStartsWith 'api-'))"For the
Get secretaction, this condition allows reading a secret only if its name starts withtest-apporapi-. All other actions pass through the condition normally.Update the condition and description on the assignment.
$testRa.Condition = $condition $testRa.Description = "Read access to secrets whose names start with test-app or api-"Use Set-AzRoleAssignment to save the change.
Set-AzRoleAssignment -InputObject $testRa -PassThru
Step 8: Clean up resources
Use Remove-AzRoleAssignment to remove the role assignment and condition.
Remove-AzRoleAssignment -ObjectId $userObjectId -RoleDefinitionName $roleDefinitionName -ResourceGroupName $resourceGroupDelete the key vault you created.
Delete the user you created.