Skip to main content

Theoretical Foundation: Manage built-in Azure roles


1. Initial Intuition​

Imagine a corporate building with different areas: the server room, financial archive, HR office, and reception. Each employee has a badge that only grants access to the doors they need to do their job. The security guard has access to all doors. The accountant has access to the financial archive but not the server room. The intern only has access to reception.

In Azure, this badge system is RBAC (Role-Based Access Control), and the "badge templates" are roles. Instead of manually defining what each person can do, you assign a role that already defines a set of permissions. Built-in roles are pre-defined templates by Microsoft that cover the most common use cases.

Azure has over 300 built-in roles, but in practice, a small set covers the vast majority of situations. Understanding how these roles work, how they are hierarchically organized, and how they are assigned is fundamental to controlling who can do what in your resources.


2. Context​

Azure RBAC is the access control system for Azure resources (VMs, storage accounts, networks, databases, etc.). It's different from Entra ID roles we saw earlier: Entra ID roles control who can administer the identity directory; Azure RBAC controls who can act on infrastructure resources.

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

The two systems coexist and are complementary, but they are independent. Being a Global Administrator in Entra ID doesn't automatically grant access to VMs or Storage Accounts. And being an Owner of an Azure subscription doesn't make the user a Global Administrator of Entra ID.

Important exception: a Global Administrator can "elevate" their own access to User Access Administrator at the Azure root scope (Root Management Group), which gives them the ability to manage RBAC assignments throughout the entire hierarchy. This elevation should be temporary and audited.


3. Building the Concepts​

3.1 The Three Elements of a Role Assignment​

A role assignment in Azure is always the combination of three elements:

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

Security Principal (who): can be a user, group, service principal (application identity), or managed identity (Azure resource managed identity).

Role Definition (what): the role definition that specifies which actions are allowed and which are denied. It's a JSON with lists of Actions, NotActions, DataActions, and NotDataActions.

Scope (where): the resource or resource container to which the permission applies.

3.2 The Scope Hierarchy​

Azure organizes resources in a four-level hierarchy. Permissions assigned at a higher level are inherited by lower levels:

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

Inheritance example: if you assign the Reader role to a user at the subscription scope, they can read all resources in all resource groups of that subscription. If you assign Contributor to a group at the scope of a specific Resource Group, all members of that group can create and manage resources in that Resource Group, but not in others.

This inheritance is always downward in the hierarchy, never upward.

3.3 The Structure of a Role Definition​

To understand built-in roles, you need to understand what composes a role definition:

FieldDescriptionExample
ActionsAllowed management operationsMicrosoft.Compute/virtualMachines/start/action
NotActionsExceptions within ActionsMicrosoft.Authorization/*/Delete
DataActionsAllowed data operationsMicrosoft.Storage/storageAccounts/blobServices/containers/blobs/read
NotDataActionsExceptions within DataActionsnone in common roles
AssignableScopesScopes where the role can be assigned/subscriptions/{id}, / (global)

The difference between Actions and DataActions is fundamental:

  • Actions control management operations: creating a VM, modifying network settings, creating a storage account. They are the "control plane".
  • DataActions control operations on data within resources: reading blobs from storage, writing messages to a queue, accessing Key Vault secrets. They are the "data plane".

A user can have permission to manage a storage account (Actions) but not to read the data stored in it (DataActions), and vice versa. This separation is an additional layer of security.

The effective permission is: (Actions - NotActions). NotActions is not an explicit denial; it's a subtraction from Actions. If role A has * in Actions and Microsoft.Authorization/*/Delete in NotActions, it means they can do everything except delete role assignments.

3.4 The Four Fundamental Roles​

Azure has over 300 built-in roles, but four are the foundation of the entire structure and are the most tested in AZ-104:

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular
RoleActionsNotActionsCan manage access?Creates resources?Reads resources?
Owner* (everything)NoneYesYesYes
Contributor* (everything)Microsoft.Authorization/*/Write, Microsoft.Authorization/*/DeleteNoYesYes
Reader*/readNoneNoNoYes
User Access AdministratorMicrosoft.Authorization/*NoneYesNoMinimum

The critical distinction between Owner and Contributor: both can create and manage any type of Azure resource. The only difference is that Contributor cannot manage RBAC role assignments (cannot grant or revoke access to other users). The Owner can.

This is essential for the principle of least privilege: if someone needs to create and manage resources but doesn't need to administer who has access, Contributor is the correct role. Giving Owner would be excessive.

The User Access Administrator role is specific: it can only manage role assignments but cannot create or configure resources. It's useful when you want to delegate access management without giving permission to modify resources.

3.5 Service-Specific Roles​

In addition to the four fundamental roles, Azure has built-in roles specific to each service. Some important examples:

RoleServiceWhat it allows
Virtual Machine ContributorComputeManage VMs, but not the associated network or storage
Virtual Machine Administrator LoginComputeLog in as administrator on VMs via Azure AD
Network ContributorNetworkingManage networks, but not VMs or access
Storage Account ContributorStorageManage storage accounts (not the data)
Storage Blob Data ReaderStorageRead blob data (DataActions, not Actions)
Storage Blob Data ContributorStorageRead and write blob data
Key Vault AdministratorKey VaultManage the vault and its secrets/keys/certificates
Key Vault Secrets UserKey VaultOnly read secrets (DataActions)
SQL DB ContributorSQLManage SQL databases, but not access or data
Monitoring ReaderMonitorRead monitoring metrics and logs
Backup ContributorBackupManage backups, but not delete vaults

The existence of granular roles like Virtual Machine Contributor versus Contributor reflects the principle of least privilege in action: an operations team that only manages VMs doesn't need access to create storage accounts or configure networks.


4. Structural View​

Permission Evaluation Flow​

When a user attempts to perform an action on an Azure resource, the system follows this flow:

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

Deny Assignments are explicit denial assignments. They are rarer (created mainly by Azure Blueprints and Azure Managed Applications), but have absolute priority over any permission. If a deny assignment exists, not even the Owner can perform the action.

Inheritance in Action: Concrete Example​

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

In this example:

  • The Audit-Group can read resources throughout the entire hierarchy (Management Group inherits downward)
  • The DevOps-Group can create and manage resources in the entire Production subscription, but not in the Dev subscription
  • The Support-Group can read the App-Frontend RG and all resources within it
  • joao@contoso.com can specifically manage the frontend-01 VM, but not other resources in the same RG

5. Practical Functioning​

Role Assignment Lifecycle​

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

Propagation: when a role assignment is created or removed, it can take up to 30 minutes for the change to fully propagate. In practical terms, this means a newly authorized user may take a few minutes to access the resource, and a user who had access revoked may still be able to access for a few minutes after revocation.

Check Effective Permissions​

Azure allows you to check what permissions a user effectively has on a resource, taking into account all assignments and inheritances:

In the portal: go to the resource > Access control (IAM) > Check access tab > select the user.

This shows all role assignments that affect that user in that scope, including those inherited from higher scopes.


6. Implementation Methods​

6.1 Azure Portal​

When to use: one-off assignments, access verification, visualizing who has access to a resource.

Path: any resource, resource group, or subscription > Access control (IAM) > Add role assignment

The portal flow has three steps:

  1. Role: select the role from the list (filtering by name helps a lot)
  2. Members: select the security principal (user, group, managed identity)
  3. Conditions (optional): add ABAC (Attribute-Based Access Control) conditions for roles like Storage Blob Data Reader/Contributor

Advantages: visual, shows role description, allows checking permissions before confirming.

Limitations: doesn't scale for multiple assignments; doesn't allow automation.

6.2 Azure CLI​

When to use: scripts, bash automation, CI/CD pipelines.

Check role assignments in a resource group:

az role assignment list \
--resource-group rg-producao \
--output table

Assign a role to a user in a resource group:

az role assignment create \
--assignee joao.silva@contoso.com \
--role "Contributor" \
--resource-group rg-producao

Assign role to a group in a subscription:

az role assignment create \
--assignee-object-id <object-id-do-grupo> \
--assignee-principal-type Group \
--role "Reader" \
--scope "/subscriptions/<subscription-id>"

Remove a role assignment:

az role assignment delete \
--assignee joao.silva@contoso.com \
--role "Contributor" \
--resource-group rg-producao

List all available roles (built-in and custom):

az role definition list --output table

Inspect the definition of a specific role:

az role definition list --name "Contributor" --output json

Advantages: scriptable, integrable with pipelines, clear syntax.

Limitations: less verbose than PowerShell for complex operations.

6.3 PowerShell (Az Module)​

When to use: complex scripts, Windows automation, detailed reports.

List role assignments in a scope:

Get-AzRoleAssignment -ResourceGroupName "rg-producao"

Assign role:

New-AzRoleAssignment `
-SignInName "joao.silva@contoso.com" `
-RoleDefinitionName "Contributor" `
-ResourceGroupName "rg-producao"

Assign role to a group by Object ID:

New-AzRoleAssignment `
-ObjectId "<object-id-do-grupo>" `
-RoleDefinitionName "Reader" `
-Scope "/subscriptions/<subscription-id>"

Remove assignment:

Remove-AzRoleAssignment `
-SignInName "joao.silva@contoso.com" `
-RoleDefinitionName "Contributor" `
-ResourceGroupName "rg-producao"

Check a user's effective permissions:

# Lists all assignments affecting a user in a subscription
Get-AzRoleAssignment -SignInName "joao.silva@contoso.com" `
-Scope "/subscriptions/<subscription-id>" `
-ExpandPrincipalGroups

The -ExpandPrincipalGroups parameter is important: it includes assignments inherited through groups the user is a member of, not just direct assignments.

6.4 Microsoft Graph and ARM API​

For advanced automation and integration with external systems, role assignments are Azure Resource Manager resources accessible via REST API:

PUT https://management.azure.com/{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentId}?api-version=2022-04-01
Content-Type: application/json

{
"properties": {
"roleDefinitionId": "/subscriptions/{subId}/providers/Microsoft.Authorization/roleDefinitions/{roleDefId}",
"principalId": "{object-id-do-security-principal}",
"principalType": "Group"
}
}

The {roleAssignmentId} is a client-generated GUID (can be a random UUID). The roleDefinitionId can be obtained with az role definition list --name "Contributor".

6.5 Azure Policy and Blueprints for Assignment at Scale​

To ensure that certain roles are always assigned on new resources or subscriptions, Azure Policy (with deployIfNotExists effect) can create role assignments automatically. This is particularly useful for ensuring that every new subscription has a standard set of role assignments.


7. Control and Security​

Role Assignment Limits​

LimitValue
Role assignments per subscription4,000
Custom roles per tenant5,000
Role assignments per Management Group500

The limit of 4,000 role assignments per subscription is frequently reached in environments with many granular direct assignments to individual users. The solution is to use groups instead of direct assignments to users: a single role assignment to a group serves all group members, consuming only 1 of the 4,000 slots.

Deny Assignments​

Deny assignments cannot be created directly by the administrator via portal or CLI. They are created automatically by:

  • Azure Blueprints: when applying a blueprint with lock, creates deny assignments to protect managed resources
  • Azure Managed Applications: protects resources managed by the application publisher
  • Azure Lighthouse: in delegated management scenarios between tenants

To view deny assignments:

az role assignment list --include-deny-assignments --output table

Privileged Identity Management (PIM)​

In environments with Entra ID P2 license, Privileged Identity Management adds a control layer over role assignments:

  • Eligible assignments: the user has the eligible role but needs to explicitly "activate" it when needed, with justification and for a limited time.
  • Active assignments: the role is permanently active, like the default RBAC behavior.

With PIM, a developer can have the Contributor role as eligible in production, activating it only when needing to make an emergency change, with configured maximum duration (e.g., 8 hours) and automatic justification logging.


8. Decision Making​

Which role to assign in each situation?​

SituationRecommended RoleReason
Admin who manages everything and needs to give access to othersOwnerOnly role with RBAC control + resource management
DevOps team that creates and manages infrastructureContributorManages resources without being able to change who has access
Auditor or analyst who only needs to viewReaderRead-only, no risk of alteration
Responsible for access management without creating resourcesUser Access AdministratorManages RBAC without creating/modifying resources
Operations that only manages VMsVirtual Machine ContributorReduced scope to what's necessary
Application that needs to read storage blobsStorage Blob Data ReaderSpecific DataActions, no control plane access
CI/CD pipeline that deploys appsContributor on specific RGScope limited to what's necessary for pipeline
Developer in sensitive production environmentEligible Contributor via PIMJust-in-time access with audit and time limit

At which scope to assign?​

SituationRecommended ScopeReason
Access to a specific resource (e.g., one VM)Individual resourceSmallest access surface
Team that manages all resources of a projectResource GroupGroups related resources without affecting other groups
Cross-cutting access to all resources in a subscriptionSubscriptionNecessary for roles like Monitoring Reader
Corporate policy that applies to all subscriptionsManagement GroupAssignment automatically propagated

9. Best Practices​

Assign roles to groups, never directly to individual users: an assignment to a group serves all members, uses only 1 slot of the 4,000 available, and greatly facilitates management: adding or removing someone from the group is sufficient, without needing to manage multiple role assignments.

Use the most restrictive scope possible: if the user only needs to manage VMs in a Resource Group, don't assign Contributor on the entire subscription. The most restrictive scope minimizes the impact of an error or credential compromise.

Prefer service-specific roles over the generic Contributor role: Virtual Machine Contributor instead of Contributor; Storage Blob Data Reader instead of Reader when the focus is data. This ensures access is exactly what's needed.

Use PIM for privileged roles: Owner and User Access Administrator especially should be eligible assignments via PIM, not permanent active assignments. Elevated access should be used only when necessary and for limited time.

Document the reason for each assignment: when creating a role assignment, use the description field (available via API and PowerShell) to record the reason. This greatly facilitates future reviews: "why does this group have Owner here?" shouldn't be an unanswered question.

Implement periodic access reviews: with Entra ID P2, Azure RBAC Access Reviews allow managers to periodically confirm if role assignments are still necessary. This combats privilege accumulation over time.


10. Common Mistakes​

Assigning Owner when Contributor would be sufficient

This is the most frequent mistake. "To ensure they can do everything they need" is the typical justification. The result is that the person can also change who has access, potentially granting excessive privileges to others. Always evaluate if the user really needs to manage role assignments or just manage resources.

Confusing Entra ID roles with Azure RBAC roles

Global Administrator is not Owner. Owner is not Global Administrator. They are completely different systems. A developer who is Owner of the subscription doesn't have access to create users in Entra ID. A Global Administrator cannot create VMs unless they also have an RBAC role assignment.

Assigning role directly to user instead of group

Over time, this consumes the 4,000 role assignment slots per subscription and makes management unfeasible. Each new employee who needs access consumes more slots, and when someone leaves the company, it's necessary to remember to remove all direct assignments scattered across multiple scopes.

Not checking effective permissions before terminating access

An administrator removes a role assignment from a user, thinking they revoked access. But the user was a member of a group that had another assignment at the same scope. Access continues. Always use "Check access" in the portal or -ExpandPrincipalGroups in PowerShell to verify effective access, not just direct assignments.

Forgetting that NotActions is not explicit denial

If role A has * in Actions and Microsoft.Authorization/*/Delete in NotActions, this means the role doesn't include the ability to delete assignments, not that it's explicitly denied. If the user has another role that includes this action, they can do it. NotActions subtracts from the current role; it doesn't block other permission sources.

Reaching the 4,000 role assignment limit

Fast-growing organizations that assign roles directly to individual users reach this limit. When the limit is reached, new assignments fail with an error and access cannot be granted. The solution is a laborious migration to group-based assignments.


11. Operation and Maintenance​

Role Assignment Auditing​

All role assignment creations and removals are logged in the Azure Activity Log:

Path: Monitor > Activity log > filter by Operation: Create role assignment or Delete role assignment

To query via PowerShell:

Get-AzLog -ResourceGroupName "rg-producao" `
-StartTime (Get-Date).AddDays(-30) |
Where-Object { $_.OperationName -like "*role*assignment*" } |
Select-Object EventTimestamp, Caller, OperationName, Status

Complete Access Inventory​

To get a report of all role assignments in a subscription:

Get-AzRoleAssignment -Scope "/subscriptions/<subscription-id>" |
Select-Object DisplayName, SignInName, RoleDefinitionName, Scope |
Export-Csv -Path "role-assignments-report.csv" -NoTypeInformation

Detect Orphaned Role Assignments​

Role assignments for users that were deleted from Entra ID appear with an Object ID without an associated name. They consume slots and should be removed:

$assignments = Get-AzRoleAssignment -Scope "/subscriptions/<subscription-id>"
$orphaned = $assignments | Where-Object {
$_.DisplayName -eq $null -and $_.SignInName -eq $null
}
$orphaned | ForEach-Object {
Write-Output "Orphaned: $($_.ObjectId) - Role: $($_.RoleDefinitionName) - Scope: $($_.Scope)"
}

Check Role Assignment Slot Usage​

$assignments = Get-AzRoleAssignment -Scope "/subscriptions/<subscription-id>"
Write-Output "Total role assignments: $($assignments.Count) / 4000"

12. Integration and Automation​

Automatic Assignment in Infrastructure Pipelines​

In Infrastructure as Code projects with Terraform or Bicep, role assignments are resources managed as code:

Bicep:

resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, principalId, contributorRoleId)
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', contributorRoleId)
principalId: principalId
principalType: 'Group'
}
}

Managing role assignments as code ensures that the desired state is always reproducible and auditable via version control.

Azure Policy Integration​

Azure Policy can ensure that certain roles are always assigned on created resources:

  • deployIfNotExists: when a Resource Group is created, automatically assigns a role to an audit group.
  • modify: modifies existing assignments for compliance.

Managed Identities and Automatic Assignments​

When a Managed Identity is created for an Azure resource (like a VM or Function App), it frequently needs role assignments to interact with other resources. For example, a VM that needs to read Key Vault secrets needs the Key Vault Secrets User role assigned to its Managed Identity.

This assignment can be automated in the deployment template:

# Create VM with system-assigned managed identity
az vm create --name minha-vm \
--resource-group rg-producao \
--assign-identity '[system]' \
...

# Get the object ID of the managed identity
IDENTITY_ID=$(az vm identity show --name minha-vm \
--resource-group rg-producao \
--query principalId -o tsv)

# Assign role to Key Vault
az role assignment create \
--assignee-object-id $IDENTITY_ID \
--assignee-principal-type ServicePrincipal \
--role "Key Vault Secrets User" \
--scope "/subscriptions/<sub-id>/resourceGroups/rg-producao/providers/Microsoft.KeyVault/vaults/meu-keyvault"

13. Final Summary​

Essential points:

  • Azure RBAC controls access to resources (VMs, storage, networks). It's different from Entra ID roles, which control the identity directory.
  • A role assignment is always the combination of: security principal (who) + role definition (what) + scope (where).
  • Permissions are inherited from top to bottom in the hierarchy: Management Group > Subscription > Resource Group > Resource.
  • Actions control management operations (control plane). DataActions control data operations (data plane).
  • NotActions doesn't explicitly deny; it subtracts actions from the current role's set.

Critical differences:

  • Owner vs. Contributor: both manage resources. Owner can also manage RBAC assignments; Contributor cannot.
  • Actions vs. DataActions: a user can manage a storage account (Actions) without being able to read the data in it (DataActions), and vice versa.
  • Deny Assignment vs. NotActions: Deny Assignment is explicit denial with maximum priority, created by Blueprints/Managed Apps, not by the administrator. NotActions only subtracts actions from a role.
  • Entra ID roles vs. Azure RBAC roles: independent systems. Global Admin is not Owner. Owner is not Global Admin.

What needs to be remembered:

  • Always assign roles to groups, never directly to individual users. This scales better and respects the 4,000 role assignment limit.
  • Use the most restrictive scope possible for each assignment.
  • The limit of 4,000 role assignments per subscription is real and can be reached in large environments with direct assignments to users.
  • After creating or removing a role assignment, it can take up to 30 minutes to propagate.
  • Role assignments for users deleted from Entra ID become orphaned in the system and consume slots. Remove them periodically.
  • The User Access Administrator role allows managing RBAC without creating resources. It's different from Owner, which does both.
  • In environments with Entra ID P2, use PIM to make privileged roles (Owner, User Access Administrator) eligible instead of permanently active.