Motivation
Managing Role Based Access Control (RBAC) authorizations for some of our major platforms I am often faced with the challenge to find the suitable role to be assigned based on error messages or fragments of information.
In this post I want to share how I approach this.
Azure PowerShell - Get-AzRoleDefinition
This Cmdlet can be used to to query a single role definition:
> Get-AzRoleDefinition -Name "Cosmos DB Account Reader Role"
Name : Cosmos DB Account Reader Role
Id : fbdf93bf-df7d-467e-a4d2-9458aa1360c8
IsCustom : False
Description : Can read Azure Cosmos DB Accounts data
Actions : {Microsoft.Authorization/*/read, Microsoft.DocumentDB/*/read, Microsoft.DocumentDB/databaseAccounts/readonlykeys/action, Microsoft.Insights/MetricDefinitions/read…}
NotActions : {}
DataActions : {}
NotDataActions : {}
AssignableScopes : {/}
It can also be used to query all Azure provisioned and custom role definitions.
If you want to find a role where a fragment of Actions
you want to assign is contained a filter on Actions
helps narrowing down:
> Get-AzRoleDefinition | %{$_.Actions -match "DocumentDB/"}
Microsoft.DocumentDB/databaseAccounts/backup/action
Microsoft.DocumentDB/databaseAccounts/restore/action
Microsoft.DocumentDB/*/read
Microsoft.DocumentDB/databaseAccounts/readonlykeys/action
Microsoft.DocumentDb/databaseAccounts/*
Microsoft.DocumentDb/databaseAccounts/*
Microsoft.DocumentDB/locations/restorableDatabaseAccounts/restore/action
Microsoft.DocumentDB/locations/restorableDatabaseAccounts/*/read
Microsoft.DocumentDB/locations/restorableDatabaseAccounts/read
With that the role definition name is lost, which contains actions found.
Conserving role definitions name for output with Get-AzRoleDefinition | %{$rd=$_;$rd.Name;$rd.Actions -match "DocumentDB/"}
shows all role definitions with actions, when those match. But we want only see role definitions, which contain matched actions.
First checking whether actions were found, output could be limited like:
> Get-AzRoleDefinition | %{$rd = $_;($rd.Actions -match "DocumentDB/").Count|?{$_ -gt 0}|%{"="*80;$rd.Name;$rd|Select-Object -ExpandProperty Actions}}
================================================================================
CosmosBackupOperator
Microsoft.DocumentDB/databaseAccounts/backup/action
Microsoft.DocumentDB/databaseAccounts/restore/action
================================================================================
Cosmos DB Account Reader Role
Microsoft.Authorization/*/read
Microsoft.DocumentDB/*/read
Microsoft.DocumentDB/databaseAccounts/readonlykeys/action
Microsoft.Insights/MetricDefinitions/read
Microsoft.Insights/Metrics/read
Microsoft.Resources/subscriptions/resourceGroups/read
Microsoft.Support/*
================================================================================
DocumentDB Account Contributor
Microsoft.Authorization/*/read
Microsoft.DocumentDb/databaseAccounts/*
Microsoft.Insights/alertRules/*
Microsoft.ResourceHealth/availabilityStatuses/read
...
which leads to the small PowerShell script findAzRoleDefinition.ps1
I regularly use
[CmdletBinding()]
param (
[Parameter(Mandatory=$true,Position=1)]
[string]
$Term
)
Get-AzRoleDefinition | %{$rd = $_;($rd.Actions -match $Term).Count|?{$_ -gt 0}|%{"="*80;$rd.Name;$rd|Select-Object -ExpandProperty Actions}}
which I then pipe into an editor like VS Code: findRoleDefinition.ps1 "Microsoft.Storage/storageAccounts" | code -
Azure CLI - az role definition
If you prefer Azure CLI a search for a fragment of a role definition action directly can be achieved with JMESPath. Challenge is that actions are nested in another array:
...
"permissions": [
{
"actions": [
"Microsoft.DocumentDB/databaseAccounts/backup/action",
"Microsoft.DocumentDB/databaseAccounts/restore/action"
],
"dataActions": [],
"notActions": [],
"notDataActions": []
}
],
...
As I did not figure out how to make the nested arrays permissions and actions searchable my approach currently only works for the assumption that there is only one entry in permissions. The process then has 2 steps
- filter role definitions for actions containing the searched string fragment
- piping the determined role definition names to another step which renders the complete role definition
Piped with PowerShell:
az role definition list --query "[].{name:name,a:join('|', permissions[0].actions)} | [?contains(a, 'DocumentDB/')].name" -o tsv | %{az role definition list -n $_}
Piped with Bash:
az role definition list --query "[].{name:name,a:join('|', permissions[0].actions)} | [?contains(a, 'DocumentDB/')].name" -o tsv | xargs -i az role definition list -n {}
Top comments (0)