I’m delighted to be kicking off Azure Spring Clean, a community event focused on Azure management best practices throughout the month of February. Many thanks to Joe Carlyle and Thomas Thornton for organising this event and allowing me to contribute.
My contribution is all about best practices for Azure Role Based Access Control. This is usually the first thing I notice when performing Azure audits or reviews for customers and is probably the best place to start when it comes to the overall governance of your Azure deployments.
Let’s start with the basics around Identity Management
The basis of your access to Azure resources is your Azure AD identity. Azure AD is cloud based and multi-tenanted and therefore it is imperative that this identity is kept secure.
Firstly, it should almost go without saying at this point that your Azure AD identity should be protected with Multi-Factor Authentication. If you haven’t already enabled this for your organisation and customers then please, please set this up as soon as possible. MFA has to be set up per tenant so if you are using your Azure AD identity as a guest user login (i.e. an external user) of another tenant then MFA needs to be enabled on that tenant also. In terms of protecting access to Azure Resource Manager tools, this can be easily achieved at no cost using the free security defaults* that Microsoft provide to every tenant otherwise conditional access policies through Azure AD Premium licensing is the recommended approach.
This Azure AD identity should uniquely identify you as an individual. Something I have seen a lot of especially in the MSP world is that IT admins like to create a generic ‘admin’ account on the customer tenant and use this account to manage the customer’s Azure subscriptions. The credentials for this account then gets shared between several engineers so it could be any one of a number of actual users who are signed into that account and performing tasks in the Azure portal or via PowerShell etc.
All user activities get logged in the activity log in Azure but if the account is being shared between users then there is no clear way to audit the activities and identify which individual performed each action. This presents a major issue from a governance point of view where there needs to be accountability of who did what and when. Therefore make sure access is assigned to a user’s individual account and avoid creating generic logins in Azure AD for managing Azure.
*Note: Security defaults are replacing Conditional Access baseline policies by the end of February 2020 which at the time of writing are still available.
Role Based Access Control (RBAC)
Put simply RBAC is used to manage access to Azure resources and control what can be done with those resources. Generally when it comes to access control we think of users but something that is often taken for granted are identities that are used for automation tasks like service principles and managed identities. These also need to be assigned access to the required resources and are managed by RBAC in the same way that user identities are.
From a governance point of view the golden rule is that all access should be based on a principle of least privilege. In other words, you should provide just enough privileges for each identity to perform its tasks or ‘role’ and that’s all.
Focusing on users here, it’s very easy to just grant full unrestricted access to every resource across your Azure subscription(s) to a group of ‘super users’ who manage everything but this is generally not good practice as an account breach would leave you heavily exposed. You also don’t usually want to provide access to Azure resources to someone who has little or no experience with those services and who could potentially make a mess of things. Depending on the size of your organisation and the scale of services deployed will help you to define the scope and access level requirements of your Azure resources. I often find it’s easier to decide this at the start of a project during whiteboarding sessions.
Azure has dozens of built in security roles that you can make use of and these should be carefully considered especially if your team is large enough to warrant using more specialised roles or where you have a lot of resources to manage that need to be divided up based on different engineer skill sets.
Depending on your organisation size my advice would be to focus (at least initially) on making use of the below three built-in RBAC roles and assigning these roles to your user security groups. For management tasks you may then look to the more granular access roles following the least privilege principle I mentioned earlier.
|Owner||Has full access to all Azure resources and can delegate access to other users|
|Contributor||Has full access to all Azure resources but can’t delegate access|
|Reader||Has read-only access to all Azure resources|
The Owner role should be used vary sparingly. If every user was made an owner then each one of those users has the potential to invite more users and grant them with whatever level of access they decide. Owners can also revoke other users’ access including that of other owners. Something I see happen a lot is that all users have been added as subscription owners either for convenience or through lack of knowledge and quite often this even includes external contractors. My advice is to limit owners to a maximum of two users.
If full control is required then instead the Contributor role should be sufficient in the majority of cases. This will allow the engineer to perform their duties without being able to grant access to other users.
The Reader role is a very useful one for performing audits, monitoring resources or for junior engineers who might be learning Azure. This role provides full visibility but will prevent the user from creating, editing or deleting any resources.
If you find that you need a more specific set of permissions for any of your users then it is possible to create your own custom RBAC roles. This is performed by means of a JSON template deployment. My personal thoughts on this one are that it should only be used if it’s a strict requirement for compliance purposes. If you go down the route of creating multiple custom roles then this can end up becoming very difficult to track especially if you are creating custom roles across multiple tenants. Another reason to avoid custom roles is that they are not supported by Azure Lighthouse for cross-customer or cross-tenant management.
The below diagram shows the scope hierarchy in Azure. In Azure Resource Manager you cannot create an Azure resource without placing it into a resource group. This resource group will belong to a particular Azure subscription. This much is a given.
Optionally, you may be using management groups to manage access across multiple subscriptions within the same tenant especially if you are an enterprise customer with a large number of Azure subscriptions.
Scope assignment works in a parent-child relationship model so whichever parent level you assign access at this gets inherited down to all child levels below this.
Deciding on which level to grant access will vary depending on your organisation or customer size. For instance, many small businesses may only have a single Azure subscription and therefore not make use of management groups at all. If you have multiple subscriptions and especially if you are likely to add more over time then management groups are the most efficient way to delegate access across multiple subscriptions rather than applying access on child levels below this.
I would like to focus more on subscriptions and resource groups in this blog post. Resource groups should be used as a location for Azure resources that share the same lifecycle, i.e. resources that are created, updated and deleted together.
A resource group should not be used as a catch all location for all of your deployed resources. Instead use separate resource groups based on the function of the resources deployed, i.e. a resource group for each service or application. This is particularly important and beneficial when you have different departments or even different service providers managing these applications. This way you are not providing unneccessary access to resources in other resource groups where access simply isn’t required.
A good example I like to use is that of a network file share. Here you would have a folder (or several folders) and within those folders you will have many files. How do you control access to these files? Well, best practice is to place each of your users into one or more security groups and assign those groups with the relevant permissions to that file share.
What you want to avoid is assigning access on a user level to individual users as before you know it you will have completely lost track of which users have access to each share. Then when a particular user’s access later needs to be changed it will be more difficult to audit that user’s current access rights and then revoke and re-assign their access.
Another thing you want to avoid in this example is assigning access on the individual file level. For the same reasons, this will be a nightmare to manage and inevitably when you need to change a user’s permissions you will then have to modify the permissions on each of those files. How long will that take???
Comparing this scenario to Azure, think of resource groups as the file shares and Azure resources as the files. The concept is the same. Ideally we don’t want to assign permissions to individual resources nor do we want to assign permissions to individual users.
Even in smaller setups where you might only ever have two or three users with any kind of access it is just not good practice to assign access in this way because things change. Users will eventually leave or change roles within the organisation and access rights will always need to be modified at some point in the future. If you have assigned access using security groups then it’s simply a matter of changing the group membership and you’re done.
Taking things a step further
Let’s be honest, we’ve all temporarily assigned someone with access to perform a particular task, right? Did we give them full admin rights temporarily and if so did we remember to remove that access afterwards?
Here’s a couple of useful tools that can help with this sort of thing.
- Instead of provisioning users with permanent access assignments, consider using Privileged Identity Management (PIM) for allowing temporary (just-in-time) access to users. This way access can go through a request for access and an approval process. If access is granted then it can be time limited so that the privileges are automatically revoked once the allotted time has elapsed. All requests and approvals are logged for later review so the compliance people will be happy.
- Use Access Reviews to audit access assignments to your security groups or applications. This can be scheduled on a recurring basis to prevent existing access assignments becoming stale over time. This is a very useful way of maintaining access assignments and making sure that only the correct individuals have access and only to the resources they require.
Note: You will need Azure AD Premium P2 licenses to use Privileged Identity Management and Access Reviews.
Finally, just to recap on some best practices that I have mentioned in this post in a concise list:
- Enforce MFA on all user accounts
- Don’t share accounts! Each user should log in with their own identity so that the activity log can be properly audited
- Assign access to security groups not to individual accounts
- Don’t assign access on the resource level where possible
- Assign access based on the least privilege access principle
- Avoid creating custom RBAC roles where possible
- Consider using Privileged Identity Management (PIM) for allowing temporary (just-in-time) access to resources
- Perform Access Reviews to prevent stale access assignments
I hope you found this article helpful, please feel free to get in touch with me via Twitter or Linked In and make sure to follow #AzureSpringClean for your daily dose of Azure management throughout February.