If you manage Azure subscriptions for your organization, you know the importance of properly managing access to resources within your subscriptions. When you started Azure, you probably use built-in roles, like owner, contributor, and other roles offered by Azure. Is it a good strategy for securing access to your organization? Are there other ways to manage access to your subscriptions?
For security and compliance concerns, the rule that should govern access management is the least privileged access. You only need to give users the minimum level of access necessary to perform their daily work. But is it possible?
In this post, we will see 3 strategies to manage roles to access Azure Subscriptions.
Built-in roles.
This strategy is the basic one, and probably the one you may use in your current organization. There is nothing’s wrong to use it. But if you need to manage you need to know that you will give your user a high level of privileges. A subscription must have at least one owner, and with the owner role, you can do anything, like bypassing policies, changing the subscription name, remove anything they want in their subscription even if they are protected by a lock. In short, they can accidentally and less often intentionally create an incident.
For memories:
Owner: This role has full access to all resources within the subscription, including the ability to create and manage resources, set access controls, and manage billing.
Contributor: This role can create and manage resources, but cannot set access controls or manage billing.
You can have a sort of moral agreement with your users, “you have all the privileges, you have all the responsibilities”, but often it ends up with “why did you let me do that?”
Once you started giving highly privileged roles to your users, it is hard to take them back. It will be more a cultural problem than a technical one.
What are the other options?
The least privileges custom roles
The opposite of the built-in roles is to create roles tailored to fit specific tasks. You create a role for only one action or a series of actions.
For example, imagine that you need to create a role for reading all extensions installed on all VMs. Permissions needed for this will be:
“Microsoft.Compute/virtualMachines/Read”
“Microsoft.Compute/virtualMachines/Extensions/Read”
“Microsoft.Resources/Subscriptions/resourceGroups/read”
The definition can be written in a JSON file
{
"Name": "VmExtensionReader",
"Id": null,
"IsCustom": true,
"Description": "Allows for read Azure V",
"Actions": [
"Microsoft.Compute/virtualMachines/Read",
"Microsoft.Compute/virtualMachines/Extensions/Read",
"Microsoft.Resources/Subscriptions/resourceGroups/read"
],
"NotActions": [],
"AssignableScopes": [
"/providers/Microsoft.Management/managementGroups/MgtGroupID"
]
}
Then we can deploy the role
New-AzRoleDefinition -InputFile "C:\CustomRoles\VmExtensionReader.json"
To find which authorization is needed to create a custom role?
You can use this page
But before creating a custom role, you will need to know exactly what the role should allow the user or service principal to do. It's perfect when the role is designed to execute a defined task, like reading some configuration or deploying some kind of workload.
But what happens if you want to apply a custom role to people who work daily in Azure? It will be more complicated to design. There will be a lot of authorization to find and manage, with a lot of error and rework. Worst, these customs roles could become obsolete each time a service is added to the allowed list or when Microsoft creates a new service.
There is another option, instead of focusing on allowed tasks, why not try to disallow tasks that shouldn’t be allowed to users
Use notAction
Let's take a look at the owner and contributor roles. They are similar, except that the contributor role could not manage access or billing.
Get-AzRoleDefinition "owner"
Name : Owner
Id : 8e3af657-a8ff-443c-a75c-2fe8c4bcb635
IsCustom : False
Description : Grants full access to manage all resources, including the ability to assign roles in Azure RBAC.
Actions : {*}
NotActions : {}
DataActions : {}
NotDataActions : {}
AssignableScopes : {/}
Now if we do the same for the contributor role
Get-AzRoleDefinition "contributor"
Name : Contributor
Id : b24988ac-6180-42a0-ab88-20f7382dd24c
IsCustom : False
Description : Grants full access to manage all resources, but does not allow you to assign roles in Azure RBAC, manage assignments in Azure Blueprints, or share image galleries.
Actions : {*}
NotActions : {Microsoft.Authorization/*/Delete, Microsoft.Authorization/*/Write, Microsoft.Authorization/elevateAccess/Action, Microsoft.Blueprint/blueprintAssignments/write…}
DataActions : {}
NotDataActions : {}
AssignableScopes : {/}
The contributor role has the same authorized action as the owner role. The only change is on NotActions
What is not action? It is the list of permissions excluded from the allowed actions. Effective access is computed by removing the notActions list from the Actions list
For the contributor role, the actions list is *
What is the noActions list
(Get-AzRoleDefinition "contributor").NotActions
Microsoft.Authorization/*/Delete
Microsoft.Authorization/*/Write
Microsoft.Authorization/elevateAccess/Action
Microsoft.Blueprint/blueprintAssignments/write
Microsoft.Blueprint/blueprintAssignments/delete
Microsoft.Compute/galleries/share/action
Here the security model does not explicitly; allow only specific tasks like in the least privileges custom roles model. Here we exclude what we think is dangerous for the organization.
Let’s look at one example. Imagine a situation where we want our users to do anything but where we want to restrict the possibility of creating, updating, or removing network peering.
The permission to edit or create a peering is “Microsoft.Network/VirtualNetworks/VirtualNetworkPeerings/write" and and the permission for deleting a peering is “Microsoft.Network/VirtualNetworks/VirtualNetworkPeerings/delete”
The JSON file corresponding to this custom role
{
"Name": "newContributorRole",
"Id": null,
"IsCustom": true,
"Description": "Contributor role without peering managenent",
"Actions": [
"*"
],
"NotActions": [
"Microsoft.Authorization/*/Delete",
"Microsoft.Authorization/*/Write",
"Microsoft.Authorization/elevateAccess/Action",
"Microsoft.Blueprint/blueprintAssignments/write",
"Microsoft.Blueprint/blueprintAssignments/delete",
"Microsoft.Compute/galleries/share/action" ,
"Microsoft.Network/VirtualNetworks/VirtualNetworkPeerings/write",
"Microsoft.Network/VirtualNetworks/VirtualNetworkPeerings/delete"
],
"AssignableScopes": [
"/providers/Microsoft.Management/managementGroups/MgtGroupID"
]
}
If you assign this role to a user, he/she will be able to do anything like a Built-in contributor, but not be able to remove, or edit existing peerings or create a new one.
This is a sample example, a real noActions custom role includes more permissions and it could be difficult to select permissions you want to exclude.
But here is the interesting part, if a new service is added to Azure, as we have a wildcard in action, it will be automatically added to the custom role.
Top comments (0)