Enhance Access Control in Azure with Access Groups
January 08, 2021 11:03I want to share with you my approach to setting appropriate access in Azure and delegate specific access control to team leaders. (Original post on LinkedIn)
When granting access to Azure for users I observe that appropriately tight control over access is brushed over and mismanaged. Often too much access, such as owner, is granted, and to way too many people. One longer-term consequence is that the team eventually spend time searching for weird bugs that “only happen in production”, just to find – much later and under pressure from dissatisfied users and screaming managers – that the real issue was that production and test was not configured the same way. Of course, automated deployments go a long way to mitigate environment drift, but the challenge with too much access, or rather inappropriate access, is that people with too much access can go willy-nilly and modify things they thought was right. This works well until it is not. Errors will always happen when humans are involved. Another issue with too much access is compliance. It is hardly compliant to allow the whole team into production environments with permanent all access.
Privileged Identity Management
This article is not about Privileged Identity Management (PIM), but I figured I would mention that as well since PIM is great technology. With PIM a user may be eligible to have a certain access, but it does not hold that privilege on a permanent basis. PIM may be configured to require managerial approval for activation. This is great because then someone with appropriate responsibility allows critical high privilege access and it is always time limited. If an account is compromised that has PIM configured for all high privilege access that account has much less value for the intruder. In relation to PIM, I advise my customers to enforce an audit after each access elevation to investigate the purpose of the required elevation and to document what was modified in the accessed environment.
The way I design appropriate and professional access to the Azure environments that belong to a team or a service is to limit scope and grant more access in development compared to production. Typically, any service hosted in Azure has multiple environments correlating to the stage it is in. The notion of “DTAP” – Development, Test, Acceptance and Production is very common. I grant the whole team read access on all environments – so that they can see all the resources they are responsible for. I only grant contributor access to development and test. For acceptance and production environments I only accept access via automated deployments using a Service Principal. Deployments must be automated for production. Acceptance is the final staging ground before production, so it is treated the same way. To acceptance and production, it is appropriate to configure PIM as discussed above to potentially allow humans to modify these environments only after appropriate access elevation.
Avoid subscription level access
I do not create a new Azure Subscription for each new service environment, because I think that is just a very big and chunky thing to deliver. It is more than what was asked for and therefore inappropriate to give. If a team receives their own subscription with full access, they tend to become careless with resources and wasteful practices ensue. The only thing you get in access control if you create more subscriptions is – more subscriptions. There is no inherent value at all for access and security. A definite downside to granting access to a whole subscription is that the access granted is not only to all resource groups and resources in the subscription at this time. Access is also granted to future resource groups that will be created. I find that the scope of resource group for access is more appropriate and relates more closely to the required access for a scenario. Subscription scope leads to the mistake of granting too much access in the future.
Azure Role Based Access Control
Role Based Access Control (RBAC) in Azure allows to assign access using a certain role to a certain scope. For example, the whole team may be readers in the service environment, but only Alice and Bob may be contributors. A scope can be a resource, a resource group or a subscription. In fact, a scope may also span multiple subscriptions. There are multiple challenges with assigning direct access to users in Azure. I will discuss them below while instead applying access via security groups.
Access using Azure AD Security Groups
When I grant access in Azure via RBAC I avoid granting it directly to humans or to service principals. Instead, I create Azure AD (AAD) security groups – called Access Groups (AG). To them I grant the access of a specific role in a specific environment. For example, foo_p_contributor_AG might be a security group in AAD for contributors on the production environment for a service called Foo. I find that putting something unique, the service name, as the prefix works well with searching in AAD. Search for that prefix and you find all AAD objects that relate to it. I proceed to grant this security group the access role of contributor in Azure for the resource group for the service foo. At this point you might think – well this is nothing new at all Magnus, it is the way access has been granted in IT forever. I agree, it is. It is just that for some reason I have yet to find an Azure project in the wild that adheres to this reasonable standard. Instead, what I see is that whole teams are owners of whole subscriptions. And mayhem ensues.
There is another excellent reason for using AG’s to grant access in Azure. Those AAD objects are security groups that are specific to the resource groups in Azure. They exist while their target resource groups exist and are only used for that context. If you grant RBAC to an AAD object in Azure and later that object is removed, the access granted remains in Azure. Azure can no longer look up in the AAD what the access was granted to. This creates an access ghost in Azure. Here you see I have granted reader access to the user Demo-Dave (he works in my office) and to a demo security group:
If I delete “temporary demo group” from my AAD the picture looks like this:
Access is granted in Azure to an object which is unknown in the AAD. I call these access ghosts.
Furthermore, if Demo-Dave leaves the company and his account is suspended access looks like this:
Yes, the same. I have visited many companies over the years where I have noted that “I probably need to talk to Dave because he has access to this service” only to find out that “Oh, Dave doesn’t work here anymore, he quit six months ago”. Azure still remembers Dave.
Azure AD Security Group Owners
Another thing that is quite nice when it comes to AAD groups is that they can have owners.
Group owners may add and remove members in the group and even add and remove other group owners. This feature creates the opportunity to effectively delegate to team leaders the authority to add and remove people to contribute to the services they manage. In Azure RBAC the same requires the owner role for the scope. The owner role allows the user to grant any role to anyone, not only selected roles. This is again inappropriate and ill advised. By setting up a security group owner for the Access Group you delegate only the ability to grant the same access to Azure that has been granted to the group. This is usually exactly appropriate for the context.
The path to improve your security posture and control in Azure
I urge everyone to invest in Azure access control and do the following:
- Add appropriately scoped access groups with roles to your service environments in Azure! Do this when you create the service environment – Reader and Contributor is a great start and it covers about 95% of your use cases. Other roles can be granted upon request and involves setting up another access group.
- Avoid granting access to subscription scope or higher! Instead, grant access to resource group scopes. Granting access to resource scope only is often too fine-grained. I prefer to segment applications over multiple resource groups with related scopes such as foo_web and foo_db.
- Remove direct human and service principal RBAC assignments from Azure! Instead, make the same members of the appropriate access groups in AAD.
- Treat your service environments in Azure as the resource group AND the collaborating AAD access groups! Remove the access groups if the Azure resource is removed.
Following this approach, you are far less likely to ever hunt environment drift bugs, there will not be any ghosts in your RBAC assignments and there will also not be any access granted to people who no longer works in the company. When you get into delegating access control via security group owners you will discover how great it is and what a wonderful yet appropriately scoped empowerment it is.
Comments are closed.