Role-based Access Control (RBAC for short) across Azure AD (and Microsoft 365 as a whole) has been a multi-year effort for Microsoft. While some of the individual workloads have their own, and in some cases very robust, permission models, the lack of single overarching solution has long plagued Microsoft 365 tenants, especially those that span multiple companies or geo-locations. On the positive side, the lack of proper RBAC support has given ISVs an opportunity to step in an offer their own solutions.
To illustrate just how long Microsoft has been working on this, the first building block of the RBAC model, namely Administrative units, was introduced back in December of 2014! I covered the initial implementation in an article dated early 2015. It took Microsoft 3 years (!) before the relevant UI bits were added to the Office 365 Admin center, which we covered back in 2018. It took them even longer to move past the initial set of roles supported, and the introduction of custom Azure AD roles. Now, at long last, Microsoft has released support for creating custom Azure AD roles for managing User objects, which complemented with the previously released support for Groups, devices, application and service principal objects finally puts the Azure AD RBAC model on the big scene. Well almost, as some bits are still in Preview, and thus should not be used in production environments just yet.
To get the list of operations currently supported for granular delegation, you can refer to the official documentation. You can also get the same details right within the Azure AD blade, when creating a new custom role. The steps are as follows: login to the Azure AD blade with a user holding the Privileged Role Administrator or Global Administrator role, go to Roles and administrators > hit the New custom role button. Provide a Name for the new role, and optional (but highly recommended) Description. You can also decide whether to start building the new role from scratch or by copying an existing role, by selecting the corresponding option under the Baseline permissions control. On the next page, Permissions, you will get the full list of granular operations currently supported by the Azure AD RBAC model.
Interestingly enough, when it comes to user operations, the list of currently supported entries is rather small. As evident from the Permissions page on the New custom role wizard, or the official documentation for that matter, we have no way to delegate access to the delete user operation, changing password or any authentication-related property, or even read/update user’s photo. In fact, out of 111 resourceActions currently listed as available for user objects under the microsoft.directory resource, only 22 are supported for granular role delegation. Then again, this is still a preview functionality, so we can expect things to change before release.
That said, even with the limited options available, we are able to go more granular than the built-in roles. For example, we can create a custom role that only allows for direct assignment of licenses to user objects. Unlike the built-in License administrator role, this custom role (let’s call it Manage Licenses Only) will not allow group-based license assignments. In addition, the built-in role also comes with some additional privileges, such as being able to open the Service Health Dashboard and work with some other parts of the Microsoft 365 Admin Center. And, like all the built-in roles, it inherits permissions from the default Directory Readers role. In effect, a user with the License administrator role has access to a lot more than just license information within the organization, even though the majority of this information is read-only. On the other hand, a custom role allows you to go much more granular even on the “read-only” permissions, and you can limit those to just the standard user properties.
Whichever individual permissions you assign to a custom role is up to you. As mentioned above, only a handful of scenarios are supported for user objects currently, but a custom role is not limited to just one type of objects to manage, and more permissions will likely become available in the future. Once you are satisfied with the selection of permissions for your new custom role, press the Next button and proceed to the Review + Create page to verify the selection, then hit the Create button to complete the process.
The newly created Azure AD admin role allows us to define which specific operations can be performed by a user that has been assigned the role. Another, and arguably even more important part of the RBAC model, is being able to specify the set of objects against which a given role will be applied. In other words, the scope of the role. In Azure AD, the scope is defined as part of a role assignment, which is basically a link between a directory principal (such as user or service principal object) and a role definition (such as the custom role we created above), granted at a specific directory scope. The scope can be a single user or group object, but most commonly represents an administrative unit object.
As an example, let’s assign our Manage Licenses Only custom role to a given user, and make sure he can only use his newly assigned privileges against users in a given AU, for example the Bulgaria users AU. To create the role assignment, go to the Azure AD blade > Administrative units > select the AU in question > Roles and administrators. Here, you should see a list of all (built-in and custom-created) Azure AD roles that support an AU-scoped role assignment. Clock on the Manage Licenses Only entry, then hit the Add assignments button. The only thing left to configure is the set of user(s) to which the role assignment will be linked to, which you can do by hitting the Select Members link. As in my case the tenant is using Privileged Identity Management, I will also have to select the assignment type and duration. Once you hit the Assign button, the relevant user(s) will be able to enjoy their newly assigned privileges, after obtaining a fresh access token that is.
Next, let’s see how the new custom role can be leveraged by the user. It’s worth re-iterating that the role we created will not allow the user to login to the Microsoft 365 Admin center, so any operations will be limited to the Azure AD blade. And since we created a role assignment at an AU scope, even within the Azure AD blade the user assigned said role will be limited to performing actions against only a subset of the users. Lastly, even for users in scope, the set of actions will be restricted to reading the user properties, updating the usage location and updating license assignments.
To illustrate the effect of assigning the scoped custom role, refer to the screenshot below. Notice the difference in the available UI elements for a user out of scope (top left) and user in scope of the role assignment (top right). The UI will automatically disable any control the user does not have permissions for, such as the list of profile properties show in the middle. While other UI elements might show as enabled, for example the Reset password button, they will show an “access denied” or “insufficient privileged” type of error when accessed. In effect, for users outside of the role assignment scope, our newly appointed admin will not be able to perform any action, not even changing their license. For users in scope, the only changes he will be able to perform is updating the Usage location property (middle right) and managing license assignments (bottom right). In addition, the Reprocess action will also be unavailable, as we did not include it in the role definition.
In effect, we have created a custom, granular role assignment, scoped to only a subset of the users of the tenant. With the newly introduced support for user objects, we can now exert granular control over each action the user will be able to perform, down to individual attributes in some cases, which serves to illustrate the flexibility of the RBAC model chosen by Azure AD. As more user-specific actions become available and other preview functionalities roll out, we will finally get to a point where Azure AD RBAC is ready to tackle the challenges posed by multi-national companies or large organizations in general. Don’t forget that this functionality requires Azure AD Premium licensing though.
Before closing, let me also mention that the configuration steps detailed above are not limited to the Azure AD UI only. Graph API offers full support for listing, creating and managing custom Azure AD roles and role assignments. In fact, some of the bits of information presented above were taken directly out of the corresponding Graph API endpoints, i.e. this endpoint gives you the list of all available resourceActions for Azure AD. Refer to the official Graph API documentation for more info. Also, I’ve definitely not covered all the intricacies of the Azure AD RBAC model, for example I didn’t talk about the other scope types available. Refer to my previous articles or the official documentation for details on those.
Oh, and let me re-iterate once again that custom roles do not inherit the default user permissions in Azure AD. This is contrary to the behavior of the built-in roles, and is controlled by the corresponding InheritsPermissionsFrom property/relationship. Keep this fact in mind when planning your custom Azure AD role implementation!