Skip to content

Commit 35e81ca

Browse files
fix: allow assignment of additional replicator roles in policy
the privilege escalation policy did as intended to prevent additional role assignments to the replicator SPN. However, this creates a conflict when trying to add additional scopes where cancelling subscriptions or deleting resource groups is allowed. We therefore now whitelist those roles assignments in the policy.
1 parent c58b9e3 commit 35e81ca

File tree

2 files changed

+50
-26
lines changed

2 files changed

+50
-26
lines changed

modules/meshcloud-replicator-service-principal/README.md

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@
33

44
| Name | Version |
55
|------|---------|
6-
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
7-
| <a name="requirement_azuread"></a> [azuread](#requirement\_azuread) | 2.18.0 |
8-
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | 3.3.0 |
6+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | > 1.0 |
7+
| <a name="requirement_azuread"></a> [azuread](#requirement\_azuread) | 2.46.0 |
8+
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | 3.81.0 |
99

1010
## Providers
1111

1212
| Name | Version |
1313
|------|---------|
14-
| <a name="provider_azuread"></a> [azuread](#provider\_azuread) | 2.18.0 |
15-
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.3.0 |
14+
| <a name="provider_azuread"></a> [azuread](#provider\_azuread) | 2.46.0 |
15+
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.81.0 |
16+
| <a name="provider_time"></a> [time](#provider\_time) | 0.11.1 |
1617

1718
## Modules
1819

@@ -22,32 +23,45 @@ No modules.
2223

2324
| Name | Type |
2425
|------|------|
25-
| [azuread_app_role_assignment.meshcloud_replicator-directory](https://registry.terraform.io/providers/hashicorp/azuread/2.18.0/docs/resources/app_role_assignment) | resource |
26-
| [azuread_app_role_assignment.meshcloud_replicator-group](https://registry.terraform.io/providers/hashicorp/azuread/2.18.0/docs/resources/app_role_assignment) | resource |
27-
| [azuread_app_role_assignment.meshcloud_replicator-user](https://registry.terraform.io/providers/hashicorp/azuread/2.18.0/docs/resources/app_role_assignment) | resource |
28-
| [azuread_application.meshcloud_replicator](https://registry.terraform.io/providers/hashicorp/azuread/2.18.0/docs/resources/application) | resource |
29-
| [azuread_service_principal.meshcloud_replicator](https://registry.terraform.io/providers/hashicorp/azuread/2.18.0/docs/resources/service_principal) | resource |
30-
| [azuread_application_password.application_pw](https://registry.terraform.io/providers/hashicorp/azuread/2.43.0/docs/resources/application_password) | resource |
31-
| [time_rotating.replicator_secret_rotation](https://registry.terraform.io/providers/hashicorp/time/0.9.1/docs/resources/rotating) | resource |
32-
| [azurerm_role_assignment.meshcloud_replicator](https://registry.terraform.io/providers/hashicorp/azurerm/3.3.0/docs/resources/role_assignment) | resource |
33-
| [azurerm_role_definition.meshcloud_replicator](https://registry.terraform.io/providers/hashicorp/azurerm/3.3.0/docs/resources/role_definition) | resource |
34-
| [azuread_application_published_app_ids.well_known](https://registry.terraform.io/providers/hashicorp/azuread/2.18.0/docs/data-sources/application_published_app_ids) | data source |
35-
| [azuread_service_principal.msgraph](https://registry.terraform.io/providers/hashicorp/azuread/2.18.0/docs/data-sources/service_principal) | data source |
26+
| [azuread_app_role_assignment.meshcloud_replicator-directory](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/resources/app_role_assignment) | resource |
27+
| [azuread_app_role_assignment.meshcloud_replicator-group](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/resources/app_role_assignment) | resource |
28+
| [azuread_app_role_assignment.meshcloud_replicator-user](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/resources/app_role_assignment) | resource |
29+
| [azuread_application.meshcloud_replicator](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/resources/application) | resource |
30+
| [azuread_application_federated_identity_credential.meshcloud_replicator](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/resources/application_federated_identity_credential) | resource |
31+
| [azuread_application_password.application_pw](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/resources/application_password) | resource |
32+
| [azuread_service_principal.meshcloud_replicator](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/resources/service_principal) | resource |
33+
| [azurerm_management_group_policy_assignment.privilege-escalation-prevention](https://registry.terraform.io/providers/hashicorp/azurerm/3.81.0/docs/resources/management_group_policy_assignment) | resource |
34+
| [azurerm_policy_definition.privilege_escalation_prevention](https://registry.terraform.io/providers/hashicorp/azurerm/3.81.0/docs/resources/policy_definition) | resource |
35+
| [azurerm_role_assignment.meshcloud_replicator](https://registry.terraform.io/providers/hashicorp/azurerm/3.81.0/docs/resources/role_assignment) | resource |
36+
| [azurerm_role_assignment.meshcloud_replicator_rg_deleter](https://registry.terraform.io/providers/hashicorp/azurerm/3.81.0/docs/resources/role_assignment) | resource |
37+
| [azurerm_role_assignment.meshcloud_replicator_subscription_canceler](https://registry.terraform.io/providers/hashicorp/azurerm/3.81.0/docs/resources/role_assignment) | resource |
38+
| [azurerm_role_definition.meshcloud_replicator](https://registry.terraform.io/providers/hashicorp/azurerm/3.81.0/docs/resources/role_definition) | resource |
39+
| [azurerm_role_definition.meshcloud_replicator_rg_deleter](https://registry.terraform.io/providers/hashicorp/azurerm/3.81.0/docs/resources/role_definition) | resource |
40+
| [azurerm_role_definition.meshcloud_replicator_subscription_canceler](https://registry.terraform.io/providers/hashicorp/azurerm/3.81.0/docs/resources/role_definition) | resource |
41+
| [time_rotating.replicator_secret_rotation](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/rotating) | resource |
42+
| [azuread_application_published_app_ids.well_known](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/data-sources/application_published_app_ids) | data source |
43+
| [azuread_application_template.enterprise_app](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/data-sources/application_template) | data source |
44+
| [azuread_service_principal.msgraph](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/data-sources/service_principal) | data source |
3645

3746
## Inputs
3847

3948
| Name | Description | Type | Default | Required |
4049
|------|-------------|------|---------|:--------:|
4150
| <a name="input_additional_permissions"></a> [additional\_permissions](#input\_additional\_permissions) | Additional Subscription-Level Permissions the Service Principal needs. | `list(string)` | `[]` | no |
4251
| <a name="input_additional_required_resource_accesses"></a> [additional\_required\_resource\_accesses](#input\_additional\_required\_resource\_accesses) | Additional AAD-Level Resource Accesses the Service Principal needs. | `list(object({ resource_app_id = string, resource_accesses = list(object({ id = string, type = string })) }))` | `[]` | no |
43-
| <a name="input_scope"></a> [scope](#input\_scope) | The scope to which Service Principal permissions should be assigned to. Usually this is the management group id of form `/providers/Microsoft.Management/managementGroups/<tenantId>` that sits atop the subscriptions. | `string` | n/a | yes |
44-
| <a name="input_service_principal_name_suffix"></a> [service\_principal\_name\_suffix](#input\_service\_principal\_name\_suffix) | Service principal name suffix. | `string` | n/a | yes |
45-
| <a name="replicator_rg_enabled"></a> [replicator\_rg\_enabled](#input\_service\_principal\_name\_suffix) | Whether the created replicator Service Principal should be usable for Azure Resource Group based replication. | `bool` | false | no |
52+
| <a name="input_assignment_scopes"></a> [assignment\_scopes](#input\_assignment\_scopes) | The scopes to which Service Principal permissions is assigned to. List of management group id of form `/providers/Microsoft.Management/managementGroups/<mgmtGroupId>/`. | `list(string)` | n/a | yes |
53+
| <a name="input_can_cancel_subscriptions_in_scopes"></a> [can\_cancel\_subscriptions\_in\_scopes](#input\_can\_cancel\_subscriptions\_in\_scopes) | The scopes to which Service Principal cancel subscription permission is assigned to. List of management group id of form `/providers/Microsoft.Management/managementGroups/<mgmtGroupId>/`. | `list(string)` | `[]` | no |
54+
| <a name="input_can_delete_rgs_in_scopes"></a> [can\_delete\_rgs\_in\_scopes](#input\_can\_delete\_rgs\_in\_scopes) | The scopes to which Service Principal delete resource group permission is assigned to. Only relevant when `replicator_rg_enabled`. List of subscription scopes of form `/subscriptions/<subscriptionId>`. | `list(string)` | `[]` | no |
55+
| <a name="input_create_password"></a> [create\_password](#input\_create\_password) | Create a password for the enterprise application. | `bool` | n/a | yes |
56+
| <a name="input_custom_role_scope"></a> [custom\_role\_scope](#input\_custom\_role\_scope) | The scope to which Service Principal permissions can be assigned to. Usually this is the management group id of form `/providers/Microsoft.Management/managementGroups/<tenantId>` that sits atop the subscriptions. | `string` | n/a | yes |
57+
| <a name="input_replicator_rg_enabled"></a> [replicator\_rg\_enabled](#input\_replicator\_rg\_enabled) | Whether the created replicator Service Principal should be usable for Azure Resource Group based replication. | `bool` | `false` | no |
58+
| <a name="input_service_principal_name"></a> [service\_principal\_name](#input\_service\_principal\_name) | Display name of the replicator service principal. | `string` | n/a | yes |
59+
| <a name="input_workload_identity_federation"></a> [workload\_identity\_federation](#input\_workload\_identity\_federation) | Enable workload identity federation instead of using a password by providing these additional settings. Usually you should receive the required settings when attempting to configure a platform with workload identity federation in meshStack. | `object({ issuer = string, subject = string })` | `null` | no |
4660

4761
## Outputs
4862

4963
| Name | Description |
5064
|------|-------------|
65+
| <a name="output_application_client_secret"></a> [application\_client\_secret](#output\_application\_client\_secret) | Client Secret Of the Application. |
5166
| <a name="output_credentials"></a> [credentials](#output\_credentials) | Service Principal application id and object id |
52-
| <a name="output_application_client_secret"></a> [application\_client\_secret](#output\_application\_client\_secret) | Password for the Service Principal. |
5367
<!-- END_TF_DOCS -->

modules/meshcloud-replicator-service-principal/module.tf

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ resource "azurerm_role_definition" "meshcloud_replicator" {
6868
}
6969

7070
resource "azurerm_role_definition" "meshcloud_replicator_subscription_canceler" {
71-
count = length(var.can_cancel_subscriptions_in_scopes) > 0 ? 1 : 0
7271
name = "${var.service_principal_name}-cancel-subscriptions"
7372
scope = var.custom_role_scope
7473
description = "Additional permissions required by meshStack replicator in order to cancel subscriptions"
@@ -83,7 +82,6 @@ resource "azurerm_role_definition" "meshcloud_replicator_subscription_canceler"
8382
}
8483

8584
resource "azurerm_role_definition" "meshcloud_replicator_rg_deleter" {
86-
count = length(var.can_delete_rgs_in_scopes) > 0 ? 1 : 0
8785
name = "${var.service_principal_name}-delete-resourceGroups"
8886
scope = var.custom_role_scope
8987
description = "Additional permissions required by meshStack replicator in order to delete Resource Groups"
@@ -194,15 +192,15 @@ resource "azurerm_role_assignment" "meshcloud_replicator" {
194192
resource "azurerm_role_assignment" "meshcloud_replicator_subscription_canceler" {
195193
for_each = toset(var.can_cancel_subscriptions_in_scopes)
196194
scope = each.key
197-
role_definition_id = azurerm_role_definition.meshcloud_replicator_subscription_canceler[0].role_definition_resource_id
195+
role_definition_id = azurerm_role_definition.meshcloud_replicator_subscription_canceler.role_definition_resource_id
198196
principal_id = azuread_service_principal.meshcloud_replicator.id
199197
depends_on = [azuread_service_principal.meshcloud_replicator]
200198
}
201199

202200
resource "azurerm_role_assignment" "meshcloud_replicator_rg_deleter" {
203201
for_each = toset(var.can_delete_rgs_in_scopes)
204202
scope = each.key
205-
role_definition_id = azurerm_role_definition.meshcloud_replicator_rg_deleter[0].role_definition_resource_id
203+
role_definition_id = azurerm_role_definition.meshcloud_replicator_rg_deleter.role_definition_resource_id
206204
principal_id = azuread_service_principal.meshcloud_replicator.id
207205
depends_on = [azuread_service_principal.meshcloud_replicator]
208206
}
@@ -231,16 +229,24 @@ resource "azuread_app_role_assignment" "meshcloud_replicator-user" {
231229
depends_on = [azuread_application.meshcloud_replicator]
232230
}
233231

232+
locals {
233+
assignable_role_definition_ids = compact([
234+
azurerm_role_definition.meshcloud_replicator.role_definition_id,
235+
azurerm_role_definition.meshcloud_replicator_subscription_canceler.role_definition_id,
236+
azurerm_role_definition.meshcloud_replicator_rg_deleter.role_definition_id
237+
])
238+
}
234239

235240
//---------------------------------------------------------------------------
236241
// Policy Definition for preventing the Application from assigning other privileges to itself
237242
// Assign it to the specified scope
238243
//---------------------------------------------------------------------------
239244
resource "azurerm_policy_definition" "privilege_escalation_prevention" {
240-
name = "meshcloud-privilege-escalation-prevention-${local.spp_hash}"
245+
name = "meshStack-privilege-escalation-prevention-${local.spp_hash}"
241246
policy_type = "Custom"
242247
mode = "All"
243-
display_name = "meshcloud Privilege Escalation Prevention"
248+
description = "Prevents assigning additional roles to the meshStack replicator service principal"
249+
display_name = "meshStack Privilege Escalation Prevention"
244250
management_group_id = var.custom_role_scope
245251

246252
policy_rule = <<RULE
@@ -254,6 +260,10 @@ resource "azurerm_policy_definition" "privilege_escalation_prevention" {
254260
{
255261
"field": "Microsoft.Authorization/roleAssignments/principalId",
256262
"equals": "${azuread_service_principal.meshcloud_replicator.object_id}"
263+
},
264+
{
265+
"field": "Microsoft.Authorization/roleAssignments/roleDefinitionId",
266+
"notIn": ${jsonencode(local.assignable_role_definition_ids)}
257267
}
258268
]
259269
},

0 commit comments

Comments
 (0)