This is part of my series on Azure Authorization.
- Azure Authorization – The Basics
- Azure Authorization – Azure RBAC Basics
- Azure Authorization – actions and notActions
- Azure Authorization – Resource Locks and Azure Policy denyActions
- Azure Authorization – Azure RBAC Delegation
- Azure Authorization – Azure ABAC (Attribute-based Access Control)
Hello again! This post will be a continuation of my series on Azure authorization where I’ll be covering how actions and notActions (and dataActions and notDataActions) work together. I will cover what they do and, more importantly, what they don’t do. If there is one place I see customers make mistakes when creating custom Azure RBAC roles, it’s with the use of notActions (and notDataActions).
In my last post I explained the structure of an Azure RBAC Role Definition. As a quick refresher, each role definition has a permissions section which consists of subsections named actions, notActions, dataActions, and notDataActions. Actions are the management plane permissions (operations on the resource) the role is granted and dataActions are the data plane actions (operations on the data stored within the resource) the role is granted.

So what about notActions and notDataActions? The notActions section subtracts permissions from the actions section while the notDataActions subtracts permissions from the notDataActions. Notice I used the word subtract and not deny. notActions and notDataActions IS NOT an explicit deny but rather a way to subtract a specific or permission or set of permissions. If a user receives a permissions from another Azure RBAC role assignment for another role which grants the permission, the user would have that permission. Azure’s authorization engine evaluates all of the permissions a user has across all Azure RBAC role assignments relevant to the resource the user is trying to perform an operation on. We’ll see this in more detail in a later post. Confusing right? Let’s explore a use case and do a compare and contrast to an AWS IAM Policy to drive this point home.

In the AWS IAM Policy above (on the left side) I’ve authored a custom IAM Policy that includes an allow rule allowing all actions on Amazon CloudWatch Logs (AWS’s parallel to a Log Analytics Workspace). The policy also includes a deny rule which explicitly denies the delete action. Finally, it contains a condition that the CloudWatch Logs instance must be tagged with a tag of environment with value of production. Any IAM Users, Groups, or Roles assigned the policy will have the ability to perform all operations on a CloudWatch Logs instance EXCEPT for the delete action if the CloudWatch Logs instance is tagged with environment=production. This is a very common way to design AWS IAM Policy where you grant all permissions then strip out risky or destructive permissions.
What if you wanted to do something similar in Azure? You might design an Azure RBAC role definition like what is pictured on the right. Here the actions section is granting all permissions on the Log Analytics resource provider and the notActions section is subtracting purge and delete. Notice that while Azure RBAC definition support conditions as well, but today they cannot be used in the same way they are used in AWS and you’d instead need to use another Azure feature such as a resource lock or Azure Policy denyAction. I’ll cover those features and the capabilities of Azure RBAC definition and assignment conditions future posts in this series. For the purposes of this post, let’s ignore that condition. Would an assignment of this role definition prevent a user from deleting a Log Analytics Workspace? Let’s try it out and see.
Here we have a user name Carl Carlson. An Azure RBAC role assignment has been created at the resource group scope for the role definition described below. This role definition includes all permissions for a log analytics workspace but removes the delete action.
{
"id": "/subscriptions/XXXXXXXX-c6c1-4b3d-bf0f-5cd4ca6b190b/providers/Microsoft.Authorization/roleDefinitions/a21541c6-401d-48b7-9149-7c3de8db2adc",
"properties": {
"roleName": "Custom - notActions Demo - Remove action",
"description": "Custom role that demonstrates notActions. This role uses a notAction to remove the delete action from a Log Analytics Workspace.",
"assignableScopes": [
"/subscriptions/XXXXXXXX-c6c1-4b3d-bf0f-5cd4ca6b190b"
],
"permissions": [
{
"actions": [
"Microsoft.OperationalInsights/*"
],
"notActions": [
"Microsoft.OperationalInsights/workspaces/delete"
],
"dataActions": [],
"notDataActions": []
}
]
}
}
When Carl attempts to delete the Log Analytics Workspace he receives an error stating that he does not have authorization to perform this action. This demonstrates that the delete action was indeed removed from the actions. Let me now drive home why this is not a deny.

I’ll now create an additional Azure RBAC role assignment at the resource group scope for the custom role described in the definition below. This role definition includes the delete action that the other role definition subtracted.
{
"id": "/subscriptions/b3b7aae7-c6c1-4b3d-bf0f-5cd4ca6b190b/providers/Microsoft.Authorization/roleDefinitions/bed940de-a64b-4601-bd47-651182f9f3e1",
"properties": {
"roleName": "Custom - notActions Demo - Add Action",
"description": "Custom role that demonstrates notActions. This role grants the delete action from a Log Analytics Workspace.",
"assignableScopes": [
"/subscriptions/b3b7aae7-c6c1-4b3d-bf0f-5cd4ca6b190b"
],
"permissions": [
{
"actions": [
"Microsoft.OperationalInsights/workspaces/delete"
],
"notActions": [],
"dataActions": [],
"notDataActions": []
}
]
}
}
This time when Carl attempts to delete the Log Analytics Workspace he is successful. This is because the action subtracted by the first role has been added back in by this second role because the Azure RBAC authorization engine looks at all permissions cumulatively.

So what do I want you to walk away with from this post? I want you to walk away with an understanding that notActions and notDataActions ARE NOT explicit denies and they are simply subtracting a permission(s) from actions or dataActions. As of today, you cannot design your roles the same way you did it in AWS (if you’re coming from there).
The next question bubbling in your mind is what tools does Microsoft provide to address this behavior of notActions and notDataActions. The answer to that is there are a lot of them. These include things like resource locks, Azure Policy denyActions, and denyAssignments. Each of these tools has benefits and considerations to their usage. Thankfully for you, I’ll be including a post on each of these features and some of the more advanced features working their way to general availability.
See you next post!





