Skip to content

Commit cf1dbe9

Browse files
authored
Fix Azure ML data exfiltration vulnerability by removing AzureMachineLearning service tag access and enforcing RBAC (#4687)
1 parent 6b13154 commit cf1dbe9

14 files changed

Lines changed: 162 additions & 207 deletions

File tree

.github/linters/.tflint.hcl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
config {
2-
call_module_type = "all"
2+
call_module_type = "local"
33
force = false
44
}
55

@@ -36,3 +36,7 @@ rule "terraform_standard_module_structure" {
3636
rule "terraform_required_version" {
3737
enabled = false
3838
}
39+
40+
rule "azurerm_resources_missing_prevent_destroy" {
41+
enabled = false
42+
}

.github/linters/.tflint_workspace_services.hcl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# This is used for TRE tags validation only.
22

33
config {
4-
call_module_type = "all"
4+
call_module_type = "local"
55
force = false
66
}
77

@@ -13,3 +13,7 @@ rule "azurerm_resource_missing_tags" {
1313
enabled = true
1414
tags = ["tre_id", "tre_workspace_id", "tre_workspace_service_id"]
1515
}
16+
17+
rule "azurerm_resources_missing_prevent_destroy" {
18+
enabled = false
19+
}

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<!-- markdownlint-disable MD041 -->
22
## 0.27.0 (Unreleased)
33
**BREAKING CHANGES**
4+
* Azure ML workspace service now requires auto group creation for RBAC; legacy service-principal role assignment fallback has been removed. ([#4687](https://github.com/microsoft/AzureTRE/pull/4687))
45
* Fix missing arguments for airlock manager requests - change in API contract ([#4544](https://github.com/microsoft/AzureTRE/issues/4544))
56
* Clarify cost label time period and aggregation scope in UI tooltips ([#4607](https://github.com/microsoft/AzureTRE/pull/4607))
67
* Transition GitHub Actions to use federated credentials. You should replace the `AZURE_CREDENTIALS` secret as described in the [cicd pre steps](https://microsoft.github.io/AzureTRE/latest/tre-admins/setup-instructions/cicd-pre-deployment-steps/). ([#4822](https://github.com/microsoft/AzureTRE/pull/4822))
78

9+
810
ENHANCEMENTS:
911
* Upgrade Guacamole to v1.6.0 with Java 17 and other security updates ([#4754](https://github.com/microsoft/AzureTRE/pull/4754))
1012
* API: Replace HTTP_422_UNPROCESSABLE_ENTITY response with HTTP_422_UNPROCESSABLE_CONTENT as per RFC 9110 ([#4742](https://github.com/microsoft/AzureTRE/issues/4742))
@@ -29,6 +31,7 @@ BUG FIXES:
2931
* Fix R configuration with incorrect quotes preventing package installation on Linux VMs ([#4657](https://github.com/microsoft/AzureTRE/issues/4657))
3032
* Add timeouts to Graph requests in API ([#4723](https://github.com/microsoft/AzureTRE/issues/4723))
3133
* Fix missing metastoreDomains for Databricks, which caused metastore outages for some domains ([#4779](https://github.com/microsoft/AzureTRE/issues/4779))
34+
* Fix data exfiltration vulnerability in Azure ML workspace service by removing unrestricted AzureMachineLearning service tag access and enforcing RBAC-based storage access ([#4660](https://github.com/microsoft/AzureTRE/issues/4660))
3235
* Fix cost display duplication when user resource is deleted - UI incorrectly reused cost data for remaining resources ([#4783](https://github.com/microsoft/AzureTRE/issues/4783))
3336
* Delete npm package lock file ([#4810](https://github.com/microsoft/AzureTRE/issues/4810))
3437

templates/workspace_services/azureml/porter.yaml

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
---
22
schemaVersion: 1.0.0
33
name: tre-service-azureml
4-
version: 0.10.0
4+
version: 1.1.2
55
description: "An Azure TRE service for Azure Machine Learning"
66
registry: azuretre
77
dockerfile: Dockerfile.tmpl
88

99
credentials:
10-
# Credentials for interacting with the AAD Auth tenant
11-
- name: auth_client_id
12-
env: AUTH_CLIENT_ID
13-
- name: auth_client_secret
14-
env: AUTH_CLIENT_SECRET
15-
- name: auth_tenant_id
16-
env: AUTH_TENANT_ID
1710
# Credentials for interacting with Azure
1811
- name: azure_tenant_id
1912
env: ARM_TENANT_ID
@@ -61,8 +54,6 @@ parameters:
6154
default: false
6255
- name: arm_environment
6356
env: ARM_ENVIRONMENT
64-
- name: azure_environment
65-
env: AZURE_ENVIRONMENT
6657
- name: enable_cmk_encryption
6758
type: boolean
6859
default: false
@@ -71,6 +62,12 @@ parameters:
7162
default: ""
7263
- name: log_analytics_workspace_name
7364
type: string
65+
- name: workspace_owners_group_id
66+
type: string
67+
description: "Object ID of the workspace owners AAD group"
68+
- name: workspace_researchers_group_id
69+
type: string
70+
description: "Object ID of the workspace researchers AAD group"
7471

7572
outputs:
7673
- name: azureml_workspace_name
@@ -142,14 +139,12 @@ install:
142139
address_space: ${ bundle.parameters.address_space }
143140
is_exposed_externally: ${ bundle.parameters.is_exposed_externally }
144141
arm_tenant_id: ${ bundle.credentials.azure_tenant_id }
145-
auth_client_id: ${ bundle.credentials.auth_client_id }
146-
auth_client_secret: ${ bundle.credentials.auth_client_secret }
147-
auth_tenant_id: ${ bundle.credentials.auth_tenant_id }
148142
arm_environment: ${ bundle.parameters.arm_environment }
149-
azure_environment: ${ bundle.parameters.azure_environment }
150143
enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption }
151144
key_store_id: ${ bundle.parameters.key_store_id }
152145
log_analytics_workspace_name: ${ bundle.parameters.log_analytics_workspace_name }
146+
workspace_owners_group_id: ${ bundle.parameters.workspace_owners_group_id }
147+
workspace_researchers_group_id: ${ bundle.parameters.workspace_researchers_group_id }
153148
backendConfig:
154149
use_azuread_auth: "true"
155150
use_oidc: "true"
@@ -181,14 +176,12 @@ upgrade:
181176
address_space: ${ bundle.parameters.address_space }
182177
is_exposed_externally: ${ bundle.parameters.is_exposed_externally }
183178
arm_tenant_id: ${ bundle.credentials.azure_tenant_id }
184-
auth_client_id: ${ bundle.credentials.auth_client_id }
185-
auth_client_secret: ${ bundle.credentials.auth_client_secret }
186-
auth_tenant_id: ${ bundle.credentials.auth_tenant_id }
187179
arm_environment: ${ bundle.parameters.arm_environment }
188-
azure_environment: ${ bundle.parameters.azure_environment }
189180
enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption }
190181
key_store_id: ${ bundle.parameters.key_store_id }
191182
log_analytics_workspace_name: ${ bundle.parameters.log_analytics_workspace_name }
183+
workspace_owners_group_id: ${ bundle.parameters.workspace_owners_group_id }
184+
workspace_researchers_group_id: ${ bundle.parameters.workspace_researchers_group_id }
192185
backendConfig:
193186
use_azuread_auth: "true"
194187
use_oidc: "true"
@@ -220,14 +213,12 @@ uninstall:
220213
address_space: ${ bundle.parameters.address_space }
221214
is_exposed_externally: ${ bundle.parameters.is_exposed_externally }
222215
arm_tenant_id: ${ bundle.credentials.azure_tenant_id }
223-
auth_client_id: ${ bundle.credentials.auth_client_id }
224-
auth_client_secret: ${ bundle.credentials.auth_client_secret }
225-
auth_tenant_id: ${ bundle.credentials.auth_tenant_id }
226216
arm_environment: ${ bundle.parameters.arm_environment }
227-
azure_environment: ${ bundle.parameters.azure_environment }
228217
enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption }
229218
key_store_id: ${ bundle.parameters.key_store_id }
230219
log_analytics_workspace_name: ${ bundle.parameters.log_analytics_workspace_name }
220+
workspace_owners_group_id: ${ bundle.parameters.workspace_owners_group_id }
221+
workspace_researchers_group_id: ${ bundle.parameters.workspace_researchers_group_id }
231222
backendConfig:
232223
use_azuread_auth: "true"
233224
use_oidc: "true"

templates/workspace_services/azureml/template_schema.json

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@
4444
"$id": "#/properties/log_analytics_workspace_name",
4545
"type": "string",
4646
"title": "Log Analytics Workspace Name"
47+
},
48+
"workspace_owners_group_id": {
49+
"$id": "#/properties/workspace_owners_group_id",
50+
"type": "string",
51+
"title": "Workspace Owners Group ID",
52+
"description": "Object ID of the workspace owners AAD group"
53+
},
54+
"workspace_researchers_group_id": {
55+
"$id": "#/properties/workspace_researchers_group_id",
56+
"type": "string",
57+
"title": "Workspace Researchers Group ID",
58+
"description": "Object ID of the workspace researchers AAD group"
4759
}
4860
},
4961
"uiSchema": {
@@ -52,6 +64,12 @@
5264
},
5365
"log_analytics_workspace_name": {
5466
"classNames": "tre-hidden"
67+
},
68+
"workspace_owners_group_id": {
69+
"classNames": "tre-hidden"
70+
},
71+
"workspace_researchers_group_id": {
72+
"classNames": "tre-hidden"
5573
}
5674
},
5775
"pipeline": {
@@ -70,6 +88,16 @@
7088
"name": "log_analytics_workspace_name",
7189
"type": "string",
7290
"value": "{{ resource.parent.properties.log_analytics_workspace_name }}"
91+
},
92+
{
93+
"name": "workspace_owners_group_id",
94+
"type": "string",
95+
"value": "{{ resource.parent.properties.workspace_owners_group_id }}"
96+
},
97+
{
98+
"name": "workspace_researchers_group_id",
99+
"type": "string",
100+
"value": "{{ resource.parent.properties.workspace_researchers_group_id }}"
73101
}
74102
]
75103
},
@@ -151,31 +179,30 @@
151179
]
152180
},
153181
{
154-
"name": "AzureML_Client",
155-
"description": "AzureML Client",
156-
"source_addresses": "{{ resource.properties.workspace_address_spaces }}",
182+
"name": "AzureML_Storage",
183+
"description": "AzureML Storage",
184+
"source_addresses": "{{ resource.properties.aml_subnet_address_prefixes }}",
157185
"destination_addresses": [
158-
"AzureActiveDirectory",
159-
"AzureResourceManager",
160-
"AzureMachineLearning"
186+
"{{ resource.properties.storage_tag }}"
161187
],
162188
"destination_ports": [
163-
"443"
189+
"443",
190+
"445"
164191
],
165192
"protocols": [
166193
"TCP"
167194
]
168195
},
169196
{
170-
"name": "AzureML_Storage",
171-
"description": "AzureML Storage",
172-
"source_addresses": "{{ resource.properties.aml_subnet_address_prefixes }}",
197+
"name": "Workspace_Authentication",
198+
"description": "Workspace VM Authentication",
199+
"source_addresses": "{{ resource.properties.workspace_address_spaces }}",
173200
"destination_addresses": [
174-
"{{ resource.properties.storage_tag }}"
201+
"AzureActiveDirectory",
202+
"AzureResourceManager"
175203
],
176204
"destination_ports": [
177-
"443",
178-
"445"
205+
"443"
179206
],
180207
"protocols": [
181208
"TCP"
@@ -297,31 +324,30 @@
297324
]
298325
},
299326
{
300-
"name": "AzureML_Client",
301-
"description": "AzureML Client",
302-
"source_addresses": "{{ resource.properties.workspace_address_spaces }}",
327+
"name": "AzureML_Storage",
328+
"description": "AzureML Storage",
329+
"source_addresses": "{{ resource.properties.aml_subnet_address_prefixes }}",
303330
"destination_addresses": [
304-
"AzureActiveDirectory",
305-
"AzureResourceManager",
306-
"AzureMachineLearning"
331+
"{{ resource.properties.storage_tag }}"
307332
],
308333
"destination_ports": [
309-
"443"
334+
"443",
335+
"445"
310336
],
311337
"protocols": [
312338
"TCP"
313339
]
314340
},
315341
{
316-
"name": "AzureML_Storage",
317-
"description": "AzureML Storage",
318-
"source_addresses": "{{ resource.properties.aml_subnet_address_prefixes }}",
342+
"name": "Workspace_Authentication",
343+
"description": "Workspace VM Authentication",
344+
"source_addresses": "{{ resource.properties.workspace_address_spaces }}",
319345
"destination_addresses": [
320-
"{{ resource.properties.storage_tag }}"
346+
"AzureActiveDirectory",
347+
"AzureResourceManager"
321348
],
322349
"destination_ports": [
323-
"443",
324-
"445"
350+
"443"
325351
],
326352
"protocols": [
327353
"TCP"

templates/workspace_services/azureml/terraform/.terraform.lock.hcl

Lines changed: 14 additions & 34 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

templates/workspace_services/azureml/terraform/acr.tf

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ resource "azurerm_container_registry" "acr" {
2020
dynamic "encryption" {
2121
for_each = var.enable_cmk_encryption ? [1] : []
2222
content {
23-
enabled = true
2423
key_vault_key_id = data.azurerm_key_vault_key.ws_encryption_key[0].id
2524
identity_client_id = data.azurerm_user_assigned_identity.ws_encryption_identity[0].client_id
2625
}

templates/workspace_services/azureml/terraform/data.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,7 @@ data "azurerm_role_definition" "storage_blob_data_contributor" {
6666
data "azurerm_role_definition" "storage_file_data_contributor" {
6767
name = "Storage File Data Privileged Contributor"
6868
}
69+
70+
data "azurerm_role_definition" "azureml_compute_operator" {
71+
name = "AzureML Compute Operator"
72+
}

templates/workspace_services/azureml/terraform/get_app_role_members.sh

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)