Part 5: RBAC & ABAC
Source: John Savill's Azure Master Class v3 - Part 3: Governance
Video Timestamps: 53:10 - 1:18:00
AZ-104 Relevance: ⭐⭐⭐⭐⭐ CRITICAL - RBAC is heavily tested
Role-Based Access Control (RBAC)
The Formula
WHO (Security Principal) + WHAT (Role) + WHERE (Scope) = Role AssignmentSecurity Principals
| Type | Description |
|---|---|
| User | Human identity in Entra ID |
| Group | Collection of users (BEST PRACTICE) |
| Service Principal | App identity |
| Managed Identity | Azure-managed app identity |
Best Practice: Assign roles to Groups, not individual users. Easier to manage.
Built-in Roles
| Role | Can Do |
|---|---|
| Owner | Everything + manage access |
| Contributor | Everything EXCEPT manage access |
| Reader | View only |
| User Access Administrator | Manage access only |
Hundreds of resource-specific roles exist: Storage Blob Data Contributor, Virtual Machine Contributor, etc.
Scope Levels
Inheritance: Role assigned at MG → inherited by all Subs, RGs, Resources below.
Key Rules
| Rule | Detail |
|---|---|
| Inheritance | Cannot be blocked |
| Additive | Multiple roles = sum of all permissions |
| No Deny | RBAC has no "deny" (Policy does) |
| Limit | 4,000 role assignments per subscription |
Control Plane vs Data Plane Roles
Control Plane = Manage the resource itself Data Plane = Access data inside the resource
| Role | Type | Example |
|---|---|---|
| Storage Account Contributor | Control | Create/delete storage accounts |
| Storage Blob Data Contributor | Data | Read/write blobs |
| Storage Blob Data Reader | Data | Read blobs only |
Best Practice: Use data plane RBAC instead of access keys when possible.
Custom Roles
When built-in roles don't fit, create custom ones.
Structure
{
"Name": "Custom VM Operator",
"Actions": [
"Microsoft.Compute/virtualMachines/start/action",
"Microsoft.Compute/virtualMachines/powerOff/action"
],
"NotActions": [],
"DataActions": [],
"NotDataActions": [],
"AssignableScopes": [
"/subscriptions/{sub-id}"
]
}| Field | Purpose |
|---|---|
| Actions | Control plane actions allowed |
| NotActions | Excluded from Actions (not a deny!) |
| DataActions | Data plane actions allowed |
| NotDataActions | Excluded from DataActions |
| AssignableScopes | Where this role can be assigned |
NotActions ≠ Deny
NotActions just excludes from a wildcard. It does NOT deny.
Example: If another role grants the permission, user still has it.
Limits
| Limit | Value |
|---|---|
| Custom roles per tenant | 5,000 (2,000 for China) |
| AssignableScopes per role | Many (be generous, avoid duplicates) |
Attribute-Based Access Control (ABAC)
Adds conditions to role assignments for fine-grained data access.
When to Use
ABAC is for scenarios where RBAC is too coarse:
- One storage account, multiple projects' data
- Access based on user attributes matching resource attributes
How It Works
Condition Examples
| Condition Type | Example |
|---|---|
| Blob index tag | User can only access blobs tagged Project=Alpha |
| Container name | User can only access container general |
| Environment | Must connect via private endpoint |
| Time-based | Only during business hours |
Custom Security Attributes
In Entra ID, you can add custom attributes to users:
- Entra ID → Protection → Custom Security Attributes
- Create attribute set (e.g., "ProjectAttributes")
- Create attribute (e.g., "PrimaryProject")
- Assign values to users (e.g., user Clark has PrimaryProject=Alpha)
ABAC Example
Storage account with blobs tagged by project:
- Blob A:
Project=Alpha - Blob B:
Project=Bravo
User Clark has custom attribute: PrimaryProject=Alpha
Condition: User's PrimaryProject must match blob's Project tag
Result: Clark can only access Blob A.
Current Limitations
- Only works with blob and queue data roles
- Only on Storage Accounts (at time of recording)
- Must use Entra auth (not access keys)
Checking Effective Access
View My Access
Portal → Any resource → Access Control (IAM) → Check access → View my access
Shows all roles you have (direct + inherited).
View Role Assignments
Portal → Resource → Access Control (IAM) → Role assignments
See everyone's access and where it came from (inherited vs direct).
PIM Integration
When assigning roles, you can now choose:
| Type | Behavior |
|---|---|
| Active | Always has the permission |
| Eligible | Must activate in PIM when needed |
Eligible is recommended for sensitive roles (P2 license required).
Mental Model
RBAC = Building Access Cards 🪪
- Card (role) lets you into certain rooms (scopes)
- Multiple cards = access to all those rooms combined
- Can't have a "banned from this room" card (no deny)
ABAC = Smart Lock 🔐
- Even with the right card, door checks: "Is your badge blue AND is it before 6pm?"
- Attributes on you + attributes on resource must match
AZ-104 Exam Tips
| Topic | Key Point |
|---|---|
| Role assignment formula | Principal + Role + Scope |
| Best practice | Assign to groups, not users |
| Inheritance | Cannot be blocked |
| Multiple roles | Permissions are additive |
| NotActions | NOT a deny, just excludes from wildcard |
| Data plane roles | Have "Data" in the name |
| Custom role limit | 5,000 per tenant |
| Role assignment limit | 4,000 per subscription |
Practical Exercises
Exercise 1: View Built-in Roles (5 min)
- Portal → Any Resource Group → Access Control (IAM) → Roles
- Find
Contributor- what permissions does it have? - Find
Storage Blob Data Reader- note it's a data plane role
Exercise 2: Check Your Access (3 min)
- Portal → Any resource → Access Control (IAM) → Check access
- View my access - see your effective roles
- Note which are inherited vs direct
Exercise 3: Create Custom Role (Optional, 10 min)
- Portal → Subscription → Access Control (IAM) → Add → Add custom role
- Clone from
Reader - Add action:
Microsoft.Compute/virtualMachines/start/action - Set assignable scope
- Review JSON tab to see structure
End of Part 5