Description
Microsoft.Authorization/roleDefinitions/write allows creation or modification of custom roles within its authorized scope. The identity needs that permission at every assignableScopes entry for the role. actions: ['*'] also includes this permission and other broad management operations unless excluded.
Creating a role definition and assigning a role to an identity are separate operations. However, expanding an already assigned role can increase its assignees’ permissions, so delegate role-management permissions carefully.
Potential impact
- Unnecessary role-modification permissions can be used to add excessive permissions to existing roles.
- Broad available scopes and excessive role assignments can increase the number of affected resources.
Remediation
- Do not grant
Microsoft.Authorization/roleDefinitions/writeto identities that do not manage roles. List required operations instead of using*. - Review
actions,notActions, data operations and role assignments together.assignableScopesdefines where a role can be assigned; it does not itself grant access. - Delegate role creation, modification and assignment only to administrators who need them. After changes, verify effective permissions and required workflows.
Examples
These subscription-scope deployments use a GUID role ID. They do not assign the role to an identity. When updating an existing role, retain its actual ID and use a role name unique within the tenant.
Before
targetScope = 'subscription'
resource roleDef 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' = {
name: guid(subscription().id, 'my-custom-role')
properties: {
roleName: 'my-custom-role'
description: 'This is a custom role'
permissions: [
{
actions: ['*']
}
]
assignableScopes: [subscription().id]
}
}
The role includes every management operation without exclusions. Assigning it grants broad permissions, including role-definition management.
After
targetScope = 'subscription'
resource roleDef 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' = {
name: guid(subscription().id, 'my-custom-role')
properties: {
roleName: 'my-custom-role'
description: 'This is a custom role'
permissions: [
{
actions: ['Microsoft.Authorization/roleDefinitions/read']
}
]
assignableScopes: [subscription().id]
}
}
Only role-definition reads are included. This is appropriate only when those reads meet the actual requirements; it does not remove permissions granted by other roles.