Module-3-Identity-and-Access-Management
Module 3: Identity and Access Management (IAM)
Azure RBAC
What is Azure RBAC? Azure Role-Based Access Control (RBAC) is a system that provides fine-grained access management for Azure resources. It allows you to assign specific permissions to users, groups, and applications at various scopes, such as the subscription, resource group, or individual resource level. RBAC helps ensure that users have only the access they need to perform their tasks, enhancing security and compliance within your Azure environment.
Permissions (what we can do) -> Role definitions (what the entire role can do) -> Role Assignments (connect with a who) -> Scope (where)
- Help Desk Role has help desk permissions
- Devs have dev permissions
- Admins have admin permissions
- etc. Two types of roles:
- Built-in roles: Predefined by Azure, covering common scenarios (e.g., Owner, Contributor, Reader).
- Custom roles: Created by you to meet specific needs, allowing you to define a unique set of permissions.
Names of roles:
- Owner: Full access to all resources, including the ability to delegate access to others. (Can do permissions)
- Contributor: Can create and manage all types of Azure resources but cannot grant access to others.
- Reader: Can view existing Azure resources but cannot make any changes.
- Others in between (e.g., Virtual Machine Contributor, Storage Account Contributor, etc.) provide more specific permissions for managing particular types of resources.
- User Access Administrator: Can manage user access to Azure resources, including assigning roles to users, groups, and applications. Kind of a lesser role than Owner that still has the ability to manage access but not manage resources themselves.
Management Plane: Azure RBAC operates in the management plane, which means it controls access to Azure resources and their management operations. It does not affect data plane operations, which are related to the actual data stored in resources (e.g., reading/writing data in a storage account). RBAC focuses on who can manage resources rather than who can access the data within those resources. Data Plane: The data plane refers to the operations that involve accessing and manipulating the data stored within Azure resources. For example, if you have a storage account, the data plane would include actions like reading or writing files to that storage account. RBAC does not control access to the data plane; instead, it controls access to the management plane, which is about managing and configuring Azure resources.
The difference between the management plane and data plane is crucial for understanding how Azure RBAC works. RBAC controls who can manage resources (management plane) but does not control who can access the data within those resources (data plane). For example, a user with Contributor role can create and manage a storage account (management plane), but they may not have permissions to read or write data to that storage account (data plane) unless they are also granted specific permissions for the data plane.
Demo: Azure RBAC (VM scoped)
Goal
Grant a user access to manage one VM (and only that VM), then compare what changes when you assign the same role at the resource group scope.
Prerequisites
- You need permission to create role assignments at the target scope. Typically that means you have Owner or User Access Administrator at the subscription/resource group/VM scope.
- You need permission to create a VM (or have an existing VM to use).
- RBAC changes can take a couple minutes to propagate.
Step 1: Create a resource group and VM (portal)
- In the Azure portal, go to Resource groups > Create.
- Create:
- Resource group:
rg-duporbac-demo - Region: pick one close to you
- Resource group:
- Go to Virtual machines > Create.
- Create a small VM:
- Name:
vm-duporbac-demo - Resource group:
rg-duporbac-demo - Image: any (Windows or Linux)
- Size: a small/cheap size
- Authentication: create a local admin username/password (Windows) or SSH key (Linux)
- Name:
- Finish the wizard and wait for deployment.
Step 2: Create a test user (Entra ID)
You want a user that does not already have broad access (so the RBAC test is meaningful).
- Go to Microsoft Entra ID > Users > New user.
- Create a user such as:
- Name: RBAC Demo User
- User principal name:
rbac-demo-user@<your-domain>
- Do not assign directory roles.
- Copy the username and temporary password.
Tip: In real environments, prefer assigning roles to a group and adding users to the group.
Step 3: Assign Reader at the VM scope
- Open the VM resource vm-duporbac-demo.
- Select Access control (IAM) > Add > Add role assignment.
- Role:
Reader - Members: select
rbac-demo-user@... - Review + assign.
Expected outcome:
- The user can view the VM’s configuration and metadata.
- The user cannot start/stop, resize, redeploy, or change settings.
Step 4: Validate Reader permissions
- Open an InPrivate/Incognito browser window.
- Sign in to the Azure portal as
rbac-demo-user@.... - Find the VM:
- If it doesn’t show up via search, browse to the resource group
rg-duporbac-demo.
- If it doesn’t show up via search, browse to the resource group
- Open vm-duporbac-demo and verify:
- You can open Overview, Activity log, and Properties.
- Try Start (or Stop) and confirm it fails with an authorization error.
Step 5: Grant VM management at VM scope
Now grant permissions to manage the VM (but still only this VM).
- Sign back in as your admin account.
- Open vm-duporbac-demo > Access control (IAM).
- Add a role assignment:
- Role:
Virtual Machine Contributor - Member:
rbac-demo-user@...
- Role:
Validate (as the demo user):
- You can Start/Stop the VM.
- You can change VM settings allowed by the role.
- You still should not be able to grant access to others.
Note: RBAC is additive. If you keep Reader and add Virtual Machine Contributor, the effective permissions are the union of both.
Step 6: Compare VM scope vs resource group scope (inheritance)
- As your admin account, go to Resource group
rg-duporbac-demo> Access control (IAM). - Assign
Virtual Machine Contributortorbac-demo-user@...at the resource group scope.
Validate (as the demo user):
- You can manage any VM in
rg-duporbac-demo(current and future). - You still can’t manage VMs in other resource groups.
Key takeaway:
- VM scope: best when someone should manage exactly one VM.
- Resource group scope: best when someone should manage a set of related resources.
- Subscription/management group scope: use carefully; permissions become broad very fast.
Optional: Role assignment with Azure CLI
If you want to see the scope string explicitly, use a command like:
-
VM scope:
az role assignment create --assignee rbac-demo-user@<your-domain> --role "Virtual Machine Contributor" --scope /subscriptions/<subId>/resourceGroups/rg-duporbac-demo/providers/Microsoft.Compute/virtualMachines/vm-duporbac-demo
-
Resource group scope:
az role assignment create --assignee rbac-demo-user@<your-domain> --role "Virtual Machine Contributor" --scope /subscriptions/<subId>/resourceGroups/rg-duporbac-demo
Cleanup
Delete the resource group rg-duporbac-demo to remove the VM and all demo resources.
Remove permissions for rbac-demo-user@... if you want to keep the user for other testing.
Delete anything else created here.
Entra ID Roles
In addition to Azure RBAC roles, Microsoft Entra ID (formerly Azure Active Directory) has its own set of directory roles that control permissions within the identity and access management system. These roles include:
- Global Administrator: Has access to all administrative features in Microsoft Entra ID and services that use Microsoft Entra ID identities. This role can manage all aspects of users, groups, and other directory resources.
- User Administrator: Can manage user accounts and groups, including creating and deleting users, resetting passwords, and managing user properties. However, they cannot manage other administrative roles or access management features.
- Application Administrator: Can manage application registrations and enterprise applications in Microsoft Entra ID. They can create and manage app registrations, configure single sign-on, and manage application proxy settings.
- Security Administrator: Can manage security-related features in Microsoft Entra ID, such as configuring security policies, managing security alerts, and overseeing identity protection features.
- Privileged Role Administrator: Can manage role assignments in Microsoft Entra ID, including assigning and removing directory roles to users and groups. They can also manage access to privileged roles and oversee the activation of eligible roles in Privileged Identity Management (PIM).
NOTE: These are for Entra ID only and not Azure resources. For example, a User Administrator can manage user accounts but cannot assign Azure RBAC roles to those users. Conversely, a User Access Administrator in Azure can assign Azure RBAC roles but does not have permissions to manage user accounts in Microsoft Entra ID.
Note: the first user will be the global administrator.
Custom roles need a P1 license.
Scope
- Directory (tenant) scope: Roles assigned at this scope apply to all resources and operations within the Microsoft Entra ID tenant. For example, a Global Administrator role assigned at the directory scope can manage all aspects of the tenant.
- Administrative unit scope: Roles can also be assigned to administrative units, which are subsets of the directory. This allows for delegation of administrative tasks to specific groups of users or resources without granting permissions across the entire tenant. For example, you could create an administrative unit for a specific department and assign a User Administrator role to manage only the users in that department.
- Application scope: Some roles can be assigned to specific applications, allowing for management of application-related permissions and settings without affecting other resources in the tenant. For example, an Application Administrator role could be assigned to manage a particular enterprise application without granting permissions to manage other applications or directory resources.
Role assignable groups: When creating custom roles, you can specify that they are only assignable to certain groups. This allows for more granular control over who can be assigned the role and helps ensure that permissions are granted only to appropriate users or groups. Note: These require a P1 license.
Demo: Entra ID Permissions
Step 1: Create a test user
- Sign in to the Azure portal as a Global Administrator or Privileged Role Administrator.
- Go to Microsoft Entra ID > Users > New user.
- Create a test account such as:
- Name: Entra Demo Admin
- User principal name:
entra-demo-admin@<your-domain>
- Do not assign any role during creation.
- Copy the username and temporary password.
Step 2: Assign an Entra ID role
- Go to Microsoft Entra ID > Roles and administrators.
- Search for and open User Administrator.
- Select Add assignments.
- Select
entra-demo-admin@<your-domain>. - Click Add.
Expected result:
- The user now has directory-level permissions for user management.
- This does not give the user Azure subscription or resource permissions.
Step 3: Validate the role in a separate session
- Open an InPrivate or Incognito browser window.
- Sign in as
entra-demo-admin@<your-domain>. - Go to Microsoft Entra ID > Users.
- Open an existing non-admin test user.
- Verify that you can perform actions such as:
- Edit basic user properties.
- Reset the user’s password.
- Create a new standard user.
Step 4: Prove it is not Azure RBAC
- While still signed in as the demo user, go to Virtual machines or Resource groups in the Azure portal.
- Try to open or manage Azure resources.
- Notice that you still do not have access unless you were separately assigned an Azure RBAC role such as Reader or Contributor.
This is the main point of the demo:
- Entra ID role: manages identities and directory features.
- Azure RBAC role: manages Azure subscriptions, resource groups, and resources.
Optional variation
If you want a more limited demo, assign Application Administrator instead and validate that the user can manage app registrations or enterprise applications, but still cannot manage Azure resources.
Cleanup
- Sign back in as your admin account.
- Go to Microsoft Entra ID > Roles and administrators > User Administrator.
- Remove the assignment for
entra-demo-admin@<your-domain>. - Delete the demo user if you no longer need it.
Azure RBAC Custom Roles
Need a name and description in the role definition
Then we need to define the permissions:
- Actions - management plane
- NotActions - management plane
- DataActions - data plane
- NotDataActions - data plane
Then we need to define the assignable scopes (where this role can be assigned). This is a list of scope strings that define where the role can be assigned. For example, you could specify that a custom role is only assignable at the resource group level or only within a specific subscription.
Note: You don't need to deny permissions in a custom role. If you only specify the Actions or DataActions you want to allow, then all other permissions are implicitly denied. The NotActions and NotDataActions properties are optional and are used to explicitly exclude certain permissions from the allowed set.
Assignable scopes:
- Root
- Management group
- Subscription
- Resource group
To configure custom roles, you require Owner or User Access Administrator permissions at the scope where you want to create the role. For example, if you want to create a custom role at the subscription level, you need to have Owner or User Access Administrator permissions for that subscription.
Another note: Custom roles are not Azure Policy - these are access permissions either in Entra ID or in Azure Subscriptions and resources - they are not about enforcing policies on resources. Custom roles are about defining specific sets of permissions that can be assigned to users, groups, or applications to control their access to Azure resources or Microsoft Entra ID features. Azure Policy, on the other hand, is a service that allows you to create, assign, and manage policies that enforce rules and effects on your resources to ensure compliance with organizational standards and regulatory requirements. Custom roles are about "who can do what" in terms of access and permissions, while Azure Policy is about "what can be done" in terms of resource configuration and compliance.
Demo: Azure RBAC Custom Role
Goal
Create a simple custom role that allows someone to read everything and start/restart virtual machines, then assign it at a resource group scope.
Suggested role idea:
- Name:
VM Operator - Custom Demo - Scope: one demo resource group
- Permissions:
Microsoft.Resources/subscriptions/resourceGroups/readMicrosoft.Compute/virtualMachines/readMicrosoft.Compute/virtualMachines/start/actionMicrosoft.Compute/virtualMachines/restart/action
Portal demo
- Go to Subscriptions and open your subscription.
- Select Access control (IAM).
- Select Add > Add custom role.
- In the Basics tab, enter:
- Custom role name:
VM Operator - Custom Demo - Description: Can read resource groups and VMs, and start or restart VMs.
- Custom role name:
- In Permissions, add these actions:
Microsoft.Resources/subscriptions/resourceGroups/readMicrosoft.Compute/virtualMachines/readMicrosoft.Compute/virtualMachines/start/actionMicrosoft.Compute/virtualMachines/restart/action
- In Assignable scopes, choose your demo subscription or a specific management group if that is where you want the role definition to live.
- Create the role.
- Go to your demo resource group.
- Select Access control (IAM) > Add role assignment.
- Assign VM Operator - Custom Demo to a test user or group.
- Validate by signing in as that user and confirming they can view the VM and start/restart it, but cannot delete it or grant access.
Cloud Shell demo (Azure CLI)
- Open Cloud Shell in the Azure portal and choose Bash.
- Set variables:
SUB_ID=$(az account show --query id -o tsv)
RG_NAME="rg-rbac-demo"
ROLE_NAME="VM Operator - Custom Demo"
- Create a role definition file:
cat > vm-operator-custom-role.json <<'EOF'
{
"Name": "VM Operator - Custom Demo",
"IsCustom": true,
"Description": "Can read resource groups and VMs, and start or restart VMs.",
"Actions": [
"Microsoft.Resources/subscriptions/resourceGroups/read",
"Microsoft.Compute/virtualMachines/read",
"Microsoft.Compute/virtualMachines/start/action",
"Microsoft.Compute/virtualMachines/restart/action"
],
"NotActions": [],
"DataActions": [],
"NotDataActions": [],
"AssignableScopes": [
"/subscriptions/${SUB_ID}"
]
}
EOF
- Replace the subscription variable in the file and create the role:
sed -i "s|\${SUB_ID}|$SUB_ID|g" vm-operator-custom-role.json
az role definition create --role-definition vm-operator-custom-role.json
- Assign the role at the resource group scope:
az role assignment create \
--assignee user@contoso.com \
--role "$ROLE_NAME" \
--scope "/subscriptions/$SUB_ID/resourceGroups/$RG_NAME"
- Validate:
az role assignment list --assignee user@contoso.com --all -o table
PowerShell demo
- Open Azure Cloud Shell PowerShell or a local PowerShell session with the Az module installed.
- Connect and set context:
Connect-AzAccount
$subscriptionId = (Get-AzContext).Subscription.Id
$roleName = "VM Operator - Custom Demo"
$resourceGroupName = "rg-rbac-demo"
- Build the custom role object from an existing role template:
$role = Get-AzRoleDefinition "Virtual Machine Contributor"
$role.Id = $null
$role.Name = $roleName
$role.Description = "Can read resource groups and VMs, and start or restart VMs."
$role.Actions.Clear()
$role.Actions.Add("Microsoft.Resources/subscriptions/resourceGroups/read")
$role.Actions.Add("Microsoft.Compute/virtualMachines/read")
$role.Actions.Add("Microsoft.Compute/virtualMachines/start/action")
$role.Actions.Add("Microsoft.Compute/virtualMachines/restart/action")
$role.NotActions.Clear()
$role.AssignableScopes.Clear()
$role.AssignableScopes.Add("/subscriptions/$subscriptionId")
New-AzRoleDefinition -Role $role
- Assign the role to a user at the resource group scope:
New-AzRoleAssignment -SignInName "user@contoso.com" -RoleDefinitionName $roleName -ResourceGroupName $resourceGroupName
- Validate the assignment:
Get-AzRoleAssignment -SignInName "user@contoso.com" -ResourceGroupName $resourceGroupName
Cleanup
- Remove the role assignment from the user or group.
- Delete the custom role definition when you are done testing.
- If needed, delete the demo resource group.
PowerShell cleanup example:
Remove-AzRoleAssignment -SignInName "user@contoso.com" -RoleDefinitionName "VM Operator - Custom Demo" -ResourceGroupName "rg-rbac-demo"
Remove-AzRoleDefinition -Name "VM Operator - Custom Demo"
Entra ID Custom Roles
Premium P1 License required Global Admin role or Privileged Role Admin role required to create custom roles in Entra ID
Much the same as the Azure RBAC custom roles, you need to define:
- Name and description
- Permissions (Actions and NotActions)
- Assignable scopes (Directory, Administrative Unit, Application)
- Optionally, you can specify that the role is only assignable to certain groups (role assignable groups) for more granular control over who can be assigned the role.
Demo: Entra ID Custom Role
Goal
Create a simple custom Entra ID role that allows a help desk style admin to read users and reset passwords, then assign it to a test user.
Suggested role idea:
- Name:
Helpdesk Password Reset - Custom Demo - Scope: Directory scope (
/) - Permissions:
microsoft.directory/users/standard/readmicrosoft.directory/users/password/update
This is different from Azure RBAC custom roles:
- Entra custom roles apply to directory objects and identity administration.
- Azure RBAC custom roles apply to subscriptions, resource groups, and Azure resources.
Portal demo
- Sign in as a Global Administrator or Privileged Role Administrator.
- Go to Microsoft Entra ID > Roles and administrators.
- Select New custom role.
- In Basics, enter:
- Name:
Helpdesk Password Reset - Custom Demo - Description: Can read users and reset passwords.
- Name:
- In Permissions, add directory permissions for:
- reading users
- resetting user passwords
- Leave the scope at the default directory scope unless you specifically want to demonstrate administrative units.
- Create the role.
- Open the new custom role and select Assignments > Add assignment.
- Assign the role to a test user such as
entra-demo-admin@<your-domain>. - Validate by signing in as that user and confirming they can open users in Entra ID and reset a non-admin user’s password.
Cloud Shell demo (Microsoft Graph via az rest)
- Open Cloud Shell in the Azure portal.
- Set variables:
ROLE_NAME="Helpdesk Password Reset - Custom Demo"
USER_UPN="entra-demo-admin@contoso.com"
USER_ID=$(az ad user show --id "$USER_UPN" --query id -o tsv)
- Create a role definition file:
cat > entra-custom-role.json <<'EOF'
{
"displayName": "Helpdesk Password Reset - Custom Demo",
"description": "Can read users and reset passwords.",
"isEnabled": true,
"rolePermissions": [
{
"allowedResourceActions": [
"microsoft.directory/users/standard/read",
"microsoft.directory/users/password/update"
]
}
]
}
EOF
- Create the custom role:
az rest \
--method POST \
--uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions" \
--headers "Content-Type=application/json" \
--body @entra-custom-role.json
- Get the new role definition ID:
ROLE_ID=$(az rest \
--method GET \
--uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions" \
--query "value[?displayName=='$ROLE_NAME'].id | [0]" -o tsv)
- Assign the role at directory scope:
cat > entra-custom-role-assignment.json <<EOF
{
"principalId": "$USER_ID",
"roleDefinitionId": "$ROLE_ID",
"directoryScopeId": "/"
}
EOF
az rest \
--method POST \
--uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments" \
--headers "Content-Type=application/json" \
--body @entra-custom-role-assignment.json
- Validate:
az rest \
--method GET \
--uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments" \
--query "value[?principalId=='$USER_ID']"
PowerShell demo (Microsoft Graph PowerShell)
- Open Cloud Shell PowerShell or a local PowerShell session.
- Connect to Microsoft Graph with the required permissions:
Connect-MgGraph -Scopes "RoleManagement.ReadWrite.Directory","Directory.Read.All"
- Create the custom role definition:
$roleParams = @{
DisplayName = "Helpdesk Password Reset - Custom Demo"
Description = "Can read users and reset passwords."
IsEnabled = $true
RolePermissions = @(
@{
AllowedResourceActions = @(
"microsoft.directory/users/standard/read",
"microsoft.directory/users/password/update"
)
}
)
}
$roleDefinition = New-MgRoleManagementDirectoryRoleDefinition -BodyParameter $roleParams
- Get the target user and assign the role:
$user = Get-MgUser -UserId "entra-demo-admin@contoso.com"
$assignmentParams = @{
PrincipalId = $user.Id
RoleDefinitionId = $roleDefinition.Id
DirectoryScopeId = "/"
}
New-MgRoleManagementDirectoryRoleAssignment -BodyParameter $assignmentParams
- Validate the assignment:
Get-MgRoleManagementDirectoryRoleAssignment -Filter "principalId eq '$($user.Id)'"
Validation idea
Sign in as the assigned demo user and test the role in Microsoft Entra ID > Users:
- Open a standard user account.
- Reset that user’s password.
- Confirm you still cannot perform unrelated higher-privilege tasks such as assigning Global Administrator.
Cleanup
- Remove the role assignment from the demo user.
- Delete the custom role definition.
- Delete the demo user if you no longer need it.
PowerShell cleanup example:
$user = Get-MgUser -UserId "entra-demo-admin@contoso.com"
$assignment = Get-MgRoleManagementDirectoryRoleAssignment -Filter "principalId eq '$($user.Id)'" | Where-Object { $_.RoleDefinitionId -eq $roleDefinition.Id }
Remove-MgRoleManagementDirectoryRoleAssignment -UnifiedRoleAssignmentId $assignment.Id
Remove-MgRoleManagementDirectoryRoleDefinition -UnifiedRoleDefinitionId $roleDefinition.Id
Case Study
Management has asked you to lock things down.
- Exec IT Team
- Development Team
Environment: One subscription, 3 resource groups:
- RG-APP1
- RG-Dev
- RG-Shared
M365 Group called Dev Group with all Devs in it. Exect IT Team group with all Exec IT in it. All Global Admins Dev has individual roles all over the place on those RGs and subscriptions. There is a couple of custom roles that aren't great.
Requirements:
- Principal of least privilege is needed.
- Restrict access
- Make it easier to manage
Solution
- Clean up existing role assignments and custom roles.
- Clean up groups and ensure RBAC will line up and is attached to groups not individual users. Devs should be in the Dev Group and that group should have the appropriate permissions, not individual users.
- Edit the custom roles
- Create a new custom role for the Devs that allows them to manage resources in RG-Dev but not RG-APP1 or RG-Shared.
- Assign the new custom role to the Dev Group at the RG-Dev scope.
- Remove any Entra permissions that are not needed. Devs don't need Entra access.