# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. # E2E Test: General/CustomSubscription_OwnerRole_Audit # Real Azure Policy: "[Deprecated]: Custom subscription owner roles should not exist" # Source: regolator/policyDefinitions/General/CustomSubscription_OwnerRole_Audit.json # # Features exercised: # - 4 double-negation blocks: not { field notEquals }, not { field notIn }, not { field notLike } # - Array wildcard aliases: permissions[*].actions[*], assignableScopes[*] # - subscription().id and concat(subscription().id, '/') # - notLike "/providers/Microsoft.Management/*" # - Deeply nested sub-resource arrays (permissions[*].actions[*]) aliases: test_aliases.json policy_definition: | { "properties": { "displayName": "[Deprecated]: Custom subscription owner roles should not exist", "policyType": "BuiltIn", "mode": "All", "parameters": { "effect": { "type": "string", "defaultValue": "Audit", "allowedValues": ["Audit", "Disabled"] } }, "policyRule": { "if": { "allOf": [ { "field": "type", "equals": "Microsoft.Authorization/roleDefinitions" }, { "field": "Microsoft.Authorization/roleDefinitions/type", "equals": "CustomRole" }, { "anyOf": [ { "not": { "field": "Microsoft.Authorization/roleDefinitions/permissions[*].actions[*]", "notEquals": "*" } } ] }, { "anyOf": [ { "not": { "field": "Microsoft.Authorization/roleDefinitions/assignableScopes[*]", "notIn": [ "[concat(subscription().id,'/')]", "[subscription().id]", "/" ] } }, { "not": { "field": "Microsoft.Authorization/roleDefinitions/assignableScopes[*]", "notLike": "/providers/Microsoft.Management/*" } } ] } ] }, "then": { "effect": "[parameters('effect')]" } } } } cases: # ========================================================================= # Custom owner role with subscription scope → audit # ========================================================================= - note: audit_custom_owner_subscription_scope resource: type: "Microsoft.Authorization/roleDefinitions" name: "custom-owner" properties: type: "CustomRole" permissions: - actions: - "*" assignableScopes: - "/subscriptions/sub-123" context: subscription: subscriptionId: "sub-123" id: "/subscriptions/sub-123" want_effect: "Audit" - note: audit_custom_owner_subscription_trailing_slash resource: type: "Microsoft.Authorization/roleDefinitions" name: "custom-owner-slash" properties: type: "CustomRole" permissions: - actions: - "*" assignableScopes: - "/subscriptions/sub-123/" context: subscription: subscriptionId: "sub-123" id: "/subscriptions/sub-123" want_effect: "Audit" - note: audit_custom_owner_root_scope resource: type: "Microsoft.Authorization/roleDefinitions" name: "custom-owner-root" properties: type: "CustomRole" permissions: - actions: - "*" assignableScopes: - "/" context: subscription: subscriptionId: "sub-123" id: "/subscriptions/sub-123" want_effect: "Audit" - note: audit_custom_owner_management_group_scope resource: type: "Microsoft.Authorization/roleDefinitions" name: "custom-owner-mg" properties: type: "CustomRole" permissions: - actions: - "*" assignableScopes: - "/providers/Microsoft.Management/managementGroups/mg1" context: subscription: subscriptionId: "sub-123" id: "/subscriptions/sub-123" want_effect: "Audit" # ========================================================================= # Custom role without owner (*) actions → pass # ========================================================================= - note: pass_custom_role_no_wildcard_actions resource: type: "Microsoft.Authorization/roleDefinitions" name: "custom-reader" properties: type: "CustomRole" permissions: - actions: - "Microsoft.Compute/virtualMachines/read" - "Microsoft.Storage/storageAccounts/read" assignableScopes: - "/subscriptions/sub-123" context: subscription: subscriptionId: "sub-123" id: "/subscriptions/sub-123" want_undefined: true # ========================================================================= # Custom owner role but NOT scoped to subscription/root/MG → pass # ========================================================================= - note: pass_custom_owner_resource_group_scope resource: type: "Microsoft.Authorization/roleDefinitions" name: "custom-owner-rg" properties: type: "CustomRole" permissions: - actions: - "*" assignableScopes: - "/subscriptions/sub-123/resourceGroups/rg1" context: subscription: subscriptionId: "sub-123" id: "/subscriptions/sub-123" want_undefined: true # ========================================================================= # BuiltIn role (not CustomRole) → pass # ========================================================================= - note: pass_builtin_role resource: type: "Microsoft.Authorization/roleDefinitions" name: "builtin-owner" properties: type: "BuiltInRole" permissions: - actions: - "*" assignableScopes: - "/" context: subscription: subscriptionId: "sub-123" id: "/subscriptions/sub-123" want_undefined: true # ========================================================================= # Wrong resource type # ========================================================================= - note: pass_wrong_type resource: type: "Microsoft.Compute/virtualMachines" name: "not-role-def" properties: type: "CustomRole" context: subscription: subscriptionId: "sub-123" id: "/subscriptions/sub-123" want_undefined: true