Ensure Azure subscriptions with custom roles have minimum permissions

Error: Azure subscriptions with custom roles are overly permissive

Bridgecrew Policy ID: BC_AZR_IAM_2
Checkov Check ID: CKV_AZURE_39
Bridgecrew Severity: CRITICAL
Prisma Cloud Severity: HIGH

Azure subscriptions with custom roles are overly permissive

Description

Subscription ownership should not include permission to create custom owner roles. The principle of least privilege should be followed and only necessary privileges be assigned instead of allowing full administrative access. Classic subscription admin roles offer basic access management and include Account Administrator, Service Administrator, and Co-Administrators.

We recommend the minimum permissions necessary be given to subscription owner accounts initially. Permissions can be added as needed by the account holder. This ensures the account holder cannot perform actions which were not intended.

Fix - Runtime

CLI Command

To provide a list of the role identified, use the following command:
az role definition list

Check for entries with assignableScope of / or a subscription, and an action of *.
To verify the usage and impact of removing the role identified, use the following command:
az role definition delete --name "rolename"

Fix - Buildtime

Terraform

Option 1

  • Resource: azurerm_role_definition
  • Argument: actions
resource "azurerm_role_definition" "example" {
    name        = "my-custom-role"
    scope       = data.azurerm_subscription.primary.id
    description = "This is a custom role created via Terraform"

    permissions {
    actions     = [
 -    "*"
 +    <selected actions>
     ]
    not_actions = []
    }

    assignable_scopes = [
    "/"
    ]
}

Option 2

  • Resource: azurerm_role_definition
  • Argument: assignable_scopes
resource "azurerm_role_definition" "example" {
    name        = "my-custom-role"
    scope       = data.azurerm_subscription.primary.id
    description = "This is a custom role created via Terraform"
    permissions {
    actions     = [
     "*"
     ]
    not_actions = []
    }

    assignable_scopes = [
+    <narrower scopes than subscriptions>
-    "/"
-   data.azurerm_subscription.primary.id
-   resource.azurerm_subscription.primary.id
    ]
}