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 CLI 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 CLI 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: Sign in to Azure
Use az login and follow the instructions to sign in as a User Access Administrator or Owner.
az loginUse az account show to get your subscription ID.
az account showInitialize a variable with your subscription ID.
subscriptionId="<subscriptionId>"
Step 2: Create a user
Use az ad user create to create a user, or find an existing user. This article uses User1 as the example.
Initialize a variable with the user's object ID.
userObjectId="<userObjectId>"
Step 3: Set up the key vault
Note
The commands in this article use Bash syntax (variable="value" and $variable). If you run them from Windows PowerShell or PowerShell 7, use PowerShell variable syntax instead ($variable = "value") and ignore the Bash history-expansion note in Step 4. The az commands themselves are identical in both shells.
Use az keyvault create to create a key vault that uses Azure RBAC as its permission model.
az keyvault create --name "<keyVaultName>" --resource-group "<resourceGroup>" --location "<location>" --enable-rbac-authorization trueGrant yourself a Key Vault data-plane role so you can create secrets. When a vault uses Azure RBAC, control-plane roles such as Owner or Contributor don't grant access to secret values. Without a data-plane role,
az keyvault secret setfails with a(Forbidden) Caller is not authorized to perform action on resourceerror for theMicrosoft.KeyVault/vaults/secrets/setSecret/actionaction.myObjectId=$(az ad signed-in-user show --query id -o tsv) vaultScope="/subscriptions/$subscriptionId/resourceGroups/<resourceGroup>/providers/Microsoft.KeyVault/vaults/<keyVaultName>" az role assignment create --assignee-object-id $myObjectId --assignee-principal-type User --role "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 az keyvault secret set to create a secret named
test-app-secret1.az keyvault secret set --vault-name "<keyVaultName>" --name "test-app-secret1" --value "<secretValue>"Note
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.az keyvault secret set --vault-name "<keyVaultName>" --name "test-db-password" --value "<secretValue>"Initialize variables with the names you used.
resourceGroup="<resourceGroup>" keyVaultName="<keyVaultName>" secretNameAllowed="test-app-secret1" secretNameDenied="test-db-password"
Step 4: 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.
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'))"For the
Get secretaction, this condition allows reading a secret only if its name starts withtest-app. All other actions (non-getSecret) are unaffected.Note
The condition must be a single-line string. Multi-line conditions are rejected. If you build the condition across multiple lines, flatten it first. For example:
condition=$(echo "$condition" | tr -s ' \n' ' ')In Bash, if history expansion is enabled, you might see
bash: !: event not foundbecause of the exclamation point (!) in the condition. Disable history expansion withset +H, then re-enable it later withset -H.Initialize the condition version and description.
conditionVersion="2.0" description="Read access to secrets whose names start with test-app"Use az role assignment create to assign the Key Vault Secrets User role with a condition to the user at resource group scope.
az role assignment create --assignee-object-id $userObjectId --scope $scope --role $roleDefinitionId --description "$description" --condition "$condition" --condition-version $conditionVersionExample output:
{ "canDelegate": null, "condition": "((!(ActionMatches{'Microsoft.KeyVault/vaults/secrets/getSecret/action'})) OR (@Resource[Microsoft.KeyVault/vaults/secrets:name] StringStartsWith 'test-app'))", "conditionVersion": "2.0", "description": "Read access to secrets whose names start with test-app", "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentId}", "name": "{roleAssignmentId}", "principalId": "{userObjectId}", "principalType": "User", "resourceGroup": "{resourceGroup}", "roleDefinitionId": "/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/4633458b-17de-408a-b874-0445c86b69e6", "scope": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}", "type": "Microsoft.Authorization/roleAssignments" }
Step 5: Test the condition
Open a new command window.
Use az login to sign in as User1.
az loginInitialize the variables you used earlier.
keyVaultName="<keyVaultName>" secretNameAllowed="test-app-secret1" secretNameDenied="test-db-password"Use az keyvault secret show to try to read the denied secret.
az keyvault secret show --vault-name $keyVaultName --name $secretNameDeniedExample output. Notice that the read fails because of the condition:
(Forbidden) Caller is not authorized to perform action on resource. If role assignments, deny assignments or role definitions changed recently, please observe propagation time. ... Code: ForbiddenByRbacRead the secret whose name starts with
test-app.az keyvault secret show --vault-name $keyVaultName --name $secretNameAllowedExample output. Notice that you can read the secret because its name starts with
test-app:{ "attributes": { }, "contentType": null, "id": "https://<keyVaultName>.vault.azure.net/secrets/test-app-secret1/<version>", "name": "test-app-secret1", "tags": {}, "value": "<secretValue>" }
Step 6: (Optional) Edit the condition
In the original command window, use az role assignment list to get the role assignment you added.
az role assignment list --assignee $userObjectId --resource-group $resourceGroupCreate a JSON file with the following format and update the
conditionanddescriptionproperties to also allow secrets whose names start withapi-.{ "canDelegate": null, "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-'))", "conditionVersion": "2.0", "description": "Read access to secrets whose names start with test-app or api-", "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentId}", "name": "{roleAssignmentId}", "principalId": "{userObjectId}", "principalName": "user1@contoso.com", "principalType": "User", "resourceGroup": "{resourceGroup}", "roleDefinitionId": "/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/4633458b-17de-408a-b874-0445c86b69e6", "roleDefinitionName": "Key Vault Secrets User", "scope": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}", "type": "Microsoft.Authorization/roleAssignments" }Use az role assignment update to update the condition.
az role assignment update --role-assignment "./path/roleassignment.json"
Step 7: Clean up resources
Use az role assignment delete to remove the role assignment and condition.
az role assignment delete --assignee $userObjectId --role "$roleDefinitionName" --resource-group $resourceGroupDelete the key vault you created.
Delete the user you created.