2.1.3.1. Design for Role-Based Access Control (RBAC)
2.1.3.1. Design for role-based access control (RBAC)
💡 First Principle: A robust authorization system defines who can do what, and where, by assigning specific permissions (roles) to identities (principals) at a defined scope, thereby enforcing the principle of least privilege.
Scenario: You are designing the access control for a production application's resource group. The DevOps team needs "Contributor" access to manage resources, but the security team wants to ensure no one, including DevOps, can delete any Virtual Networks within that resource group.
Azure RBAC provides fine-grained access management for Azure resources.
RBAC Core Components:
- Security Principal (Who):
- Definition: Identities that request access—users, groups, service principals (for applications), and managed identities (for Azure services).
- Design Consideration: Organize these using groups for easier management and automation, minimizing direct assignments to individual users.
- Role Definition (What):
- Definition: A set of permissions. Azure provides built-in roles:
- Owner: Full management, including access control.
- Contributor: Manage resources, not access.
- Reader: View resources only.
- User Access Administrator: Manage access assignments.
- Design Consideration: Use built-in roles for standard needs. Create custom roles when built-ins are too broad or too narrow, tailoring permissions to specific job functions.
- Definition: A set of permissions. Azure provides built-in roles:
- Scope (Where):
- Definition: Defines where access applies: management group, subscription, resource group, or individual resource.
- Design Consideration: Assign roles at the lowest possible scope to reduce risk and enforce least privilege.
Design decisions in practice:
| Decision | Guidance |
|---|---|
| Which role | Start from the narrowest BUILT-IN role that covers the task. Custom roles carry maintenance as providers add operations, so create one only when no built-in role fits |
| Which scope | Assign at the narrowest scope that still covers the requirement — management group, subscription, resource group, or individual resource. Inheritance flows down, so a resource-group assignment covers resources created there later |
| Which principal | Assign to groups, not users. A per-user assignment has to be repeated and, more importantly, unwound when someone changes role |
| Standing vs just-in-time | Privileged roles should be PIM-eligible rather than permanently assigned, so activation is time-bound, justified and auditable |
Azure RBAC is purely additive, and that single property explains most exam answers.
There is no "deny" rule an administrator can add on top of an assignment — if two
assignments overlap, the union applies. So the only way to withhold an action is to
never grant it, which means either a narrower built-in role or a custom role with the
operation left out of Actions.
Deny assignments do exist and they do beat role assignments, but customers cannot create them: Azure produces them itself, for managed applications and formerly for Blueprints, and they are read-only through RBAC. An option offering to "create a deny assignment" is describing something the portal will not let you do.
⚠️ Exam Trap: a resource lock is not access control. CanNotDelete blocks deletion
for everyone, including the people who should be able to delete, and anyone holding
the permission to manage locks can remove it. It protects against accident, not against
privilege.
⚠️ Common Pitfall: Assigning roles at a higher scope than necessary (e.g., giving a user "Contributor" on a subscription when they only need it on a single resource group). This violates the principle of least privilege and increases the potential blast radius of a compromised account.
Key Trade-Offs:
- Built-in Roles vs. Custom Roles: Built-in roles are simpler to manage but may be too permissive. Custom roles provide precise permissions but require more effort to create and maintain.
Practical Implementation: Creating a Custom Role with Azure CLI
# 1. Get the JSON definition for the built-in 'Reader' role
az role definition list --name "Reader" > reader_role.json
# 2. Modify reader_role.json to add a specific write permission
# (e.g., "Microsoft.Storage/storageAccounts/write")
# 3. Create the custom role from the modified JSON file
az role definition create --role-definition @reader_role.json
Reflection Question: How does designing for Azure RBAC (using built-in roles, custom roles, and deny assignments at appropriate scopes) fundamentally enable precise control by defining who can do what, and where, thereby enforcing the principle of least privilege and ensuring secure resource management?