If you're building a cloud service with just a few of your closest friends, you can forgiven for not thinking about securing your resources—allowing everyone in the team to do anything to all resources in the subscription may be a fine strategy. But if your team is a part of a big company, with multiple teams sharing the same subscriptions, it's another story. Ensuring that people outside your team can't modify, or in some cases see your resources may be critical to the success of your project.
Fortunately, Azure's Role-Based Access Control (RBAC) solves this problem by allowing you to assign fine-grained permissions that dictate who can do what which resources. However it isn't always obvious how to use the power of Azure RBAC to achieve the best result in a typical enterprise development scenario. But fear not, I'm here to help!
In a nutshell, Azure RBAC is about putting people (users or groups) into roles (built-in or custom) at a defined scope (subscription, resource group or resource). There are an awful lot of possible permutations here, but in practice only a few of them make sense.
The following diagram shows a canonical enterprise Azure RBAC model within a subscription. The roles (well, some of them) are in the columns and the scopes (at subscription and resource group level) are in the rows. The assignments are in the intersections—the group icons show just an example of what's possible.
First, let's look a the golden guy. He or she has full access to everything in the subscription, the keys to the castle. This role assignment applies automatically to the subscription owner, which will ideally be a service account. You can put other people in this role, but in an enterprise scenario you won't want to give mere mortals such power and responsibility. However one key thing that this role can do is both create new resource groups, and assign permissions on those groups. You'll see why this is important shortly.
Now, let's look at the other subscription-level assignments. In this model, normal members of a development team are not granted any subscription-level rights, in particular we don't grant them Contributor, which would allow them to create new resource groups. Instead we reserve subscription-level role assignments for these situations:
- Subscription Reader role, for people who have a need to view (but not change) any resources deployed in the subscription
- Subscription "specialist" roles, for people who deal with specific technologies across any resource group. For example a network engineer may be granted "Network Contributors" so they can view and modify network resources (but nothing else) in any resource group.
Project team members are assigned permissions at the resource group scope. In most cases, you would assign them Contributor access which will allow them to do everything to any resources within that resource group, including creating and deleting resources. The only difference between Owner and Contributor is that Owners can also set RBAC permissions. We don't want to allow this in this model as in an enterprise situation you typically want to control access centrally rather than delegate it to individual teams.
You may also want to assign people to less-privileged role within an individual resource group, for example Reader or one of the specialist roles if they are working on a specific project but don't need full access to all resources.
This whole model is predicated on resource groups being "pre-created" for a project team to work in, with appropriate permissions set up by a central process, team and/or tools. Again, this model isn't going to be appropriate for small organisations or perhaps for development or sandpit subscriptions. But in a large enterprise environment, this kind of governance is usually required. In my next post I'll describe what this may look like in more detail.
Finally, a few more tips on effective industrial-scale RBAC:
- Avoid role assignments at the resource level (for example, on an individual Virtual Machine). While there may be valid scenarios for this, setting permission at such a granular level is likely to be hard to manage and cause confusion.
- Use built-in roles where possible. Custom roles are a powerful and sometimes useful capability, but they should be reserved for cases when you really need them as they can also introduce complexity. There are 38 built-in roles which should cover most normal scenarios.
- Assign access to groups, not users. The Azure Portal is not really the ideal place to define who is working in which teams. A better approach is to put the users into a Group (in AAD directly, or in AD synced to AAD) and then grant Azure permissions to the group. This way you can add and remove group members externally to Azure, with permissions always being current, while also allowing that group to be used for other purposes such as mailing lists.
- Don't use Microsoft Accounts. Azure access can be assigned to users in your Azure Active Directory, or to personal Microsoft Accounts. In an enterprise scenario, Microsoft Accounts are normally a bad idea, as they aren't associated with an organisation who can do things like disable their account when they leave the company. If you're collaborating with people from outside your organisation, AAD B2B Collaboration can be used to invite those external users as "guests" in your directory.
- Don't forget Service Accounts! In a mature team, most deployments and resource changes should be made by automated processes such as CI/CD or Azure Automation scripts, rather than by individual users. If this applies to you, make sure your RBAC supports this by limiting rights to deploy resources to service accounts instead of users.
The model and tips described in this article have been derived from the requirements and solutions I've seen from a number of large organisations adopting Azure, but every team and every company are different, and you should feel free to use the available tools in whatever way works best for you. If you've got some experiences to share, I'd love to hear them in the comments.