Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f5e716b
Add malware scanning to workspace storage account
SiobhanBaynes Mar 10, 2025
abb0309
Pass env var down to porter
SiobhanBaynes Mar 10, 2025
67b3715
Add STORAGE_ACCOUNT_NAME_EXPORT_INPROGRESS to the topics to dismiss
SiobhanBaynes Mar 10, 2025
40dba6a
Add to resource processor config
SiobhanBaynes Mar 10, 2025
22144d3
Update versions
SiobhanBaynes Mar 11, 2025
fc982e5
Add topic for malware scanning in export
SiobhanBaynes Mar 13, 2025
fee4f0a
Add new topic for export
SiobhanBaynes Mar 14, 2025
8e9e54f
Pass scan result topic name through from core to workspace
SiobhanBaynes Mar 20, 2025
b74d379
Remove test files
SiobhanBaynes Mar 20, 2025
7d455e8
Restore single quotes
SiobhanBaynes Mar 20, 2025
52e2ddb
Bump core version
SiobhanBaynes Mar 20, 2025
fcfc633
Merge branch 'main' into enable_malware_scanning
SiobhanBaynes Mar 20, 2025
161b182
Bump version to 12.8
SiobhanBaynes Mar 20, 2025
f3bbfa4
Change to use `local` instead of `var`
SiobhanBaynes Mar 20, 2025
eb2f471
Fix logic as per PR comments.
SiobhanBaynes Mar 20, 2025
1159c04
Merge branch 'main' into enable_malware_scanning
SiobhanBaynes Mar 20, 2025
0fff820
Merge branch 'main' into enable_malware_scanning
SiobhanBaynes Mar 25, 2025
79659d1
Use rp_bundle to transfer vars to workspace
SiobhanBaynes Mar 25, 2025
61d3d9c
Update templates/workspaces/base/porter.yaml
SiobhanBaynes Mar 25, 2025
4501c89
Rename malware scanning parameter
SiobhanBaynes Mar 25, 2025
22f83eb
Merge branch 'enable_malware_scanning' of https://github.com/SiobhanB…
SiobhanBaynes Mar 25, 2025
666028c
Merge branch 'main' into enable_malware_scanning
SiobhanBaynes Mar 25, 2025
81991d4
Rename scan result topic name parameter
SiobhanBaynes Mar 25, 2025
5ef2932
Merge branch 'enable_malware_scanning' of https://github.com/SiobhanB…
SiobhanBaynes Mar 25, 2025
22f1698
Fix argument
SiobhanBaynes Mar 25, 2025
1b59a21
Merge branch 'main' into enable_malware_scanning
SiobhanBaynes Mar 26, 2025
c39deb9
Bump core version
SiobhanBaynes Mar 26, 2025
6ea703e
Merge branch 'main' into enable_malware_scanning
SiobhanBaynes Mar 26, 2025
9b67b5d
Merge branch 'main' into enable_malware_scanning
SiobhanBaynes Mar 27, 2025
0ac4d53
Merge branch 'main' into enable_malware_scanning
SiobhanBaynes Mar 28, 2025
5ca572e
Merge branch 'main' into enable_malware_scanning
marrobi Apr 1, 2025
1b788f5
Merge branch 'main' into enable_malware_scanning
marrobi Apr 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion airlock_processor/BlobCreatedTrigger/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def main(msg: func.ServiceBusMessage,
logging.error("environment variable 'ENABLE_MALWARE_SCANNING' does not exists. Cannot continue.")
raise

if enable_malware_scanning and constants.STORAGE_ACCOUNT_NAME_IMPORT_INPROGRESS in topic:
if enable_malware_scanning and (constants.STORAGE_ACCOUNT_NAME_IMPORT_INPROGRESS in topic or constants.STORAGE_ACCOUNT_NAME_EXPORT_INPROGRESS in topic):
# If malware scanning is enabled, the fact that the blob was created can be dismissed.
# It will be consumed by the malware scanning service
logging.info('Malware scanning is enabled. no action to perform.')
Expand Down
2 changes: 1 addition & 1 deletion airlock_processor/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.8.3"
__version__ = "0.8.4"
4 changes: 4 additions & 0 deletions core/terraform/airlock/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ output "event_grid_status_changed_topic_resource_id" {
output "event_grid_airlock_notification_topic_resource_id" {
value = azurerm_eventgrid_topic.airlock_notification.id
}

output "airlock_malware_scan_result_topic_name" {
value = local.scan_result_topic_name
}
4 changes: 4 additions & 0 deletions core/terraform/json-to-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ jq -r '
{
"path": "event_grid_airlock_notification_topic_resource_id",
"env_var": "EVENT_GRID_AIRLOCK_NOTIFICATION_TOPIC_RESOURCE_ID"
},
{
"path": "airlock_malware_scan_result_topic_name",
"env_var": "AIRLOCK_MALWARE_SCAN_RESULT_TOPIC_NAME"
}
]
as $env_vars_to_extract
Expand Down
2 changes: 2 additions & 0 deletions core/terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ module "resource_processor_vmss_porter" {
enable_cmk_encryption = var.enable_cmk_encryption
key_store_id = local.key_store_id
kv_encryption_key_name = local.cmk_name
enable_airlock_malware_scanning = var.enable_airlock_malware_scanning
airlock_malware_scan_result_topic_name = module.airlock_resources.airlock_malware_scan_result_topic_name

depends_on = [
module.network,
Expand Down
8 changes: 5 additions & 3 deletions core/terraform/resource_processor/vmss_porter/locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ locals {
rp_bundle_values_all = merge(var.rp_bundle_values, {
// Add any additional settings like ones from the config.yaml here
// to make them available for bundles.
firewall_sku = var.firewall_sku
enable_cmk_encryption = var.enable_cmk_encryption
key_store_id = var.key_store_id
firewall_sku = var.firewall_sku
enable_cmk_encryption = var.enable_cmk_encryption
key_store_id = var.key_store_id
enable_airlock_malware_scanning = var.enable_airlock_malware_scanning
airlock_malware_scan_result_topic_name = var.airlock_malware_scan_result_topic_name
})
rp_bundle_values_dic = [for key in keys(local.rp_bundle_values_all) : "RP_BUNDLE_${key}=${local.rp_bundle_values_all[key]}"]
rp_bundle_values_formatted = join("\n ", local.rp_bundle_values_dic)
Expand Down
10 changes: 10 additions & 0 deletions core/terraform/resource_processor/vmss_porter/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,13 @@ variable "kv_encryption_key_name" {
type = string
description = "Name of Key Vault Encryption Key (only used if enable_cmk_encryption is true)"
}

variable "enable_airlock_malware_scanning" {
type = bool
description = "If False, Airlock requests will skip the malware scanning stage"
}

variable "airlock_malware_scan_result_topic_name" {
type = string
Comment thread
SiobhanBaynes marked this conversation as resolved.
description = "Name of the topic to publish Airlock malware scan results to"
}
2 changes: 1 addition & 1 deletion core/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.12.10"
__version__ = "0.12.11"
28 changes: 21 additions & 7 deletions templates/workspaces/base/porter.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
schemaVersion: 1.0.0
name: tre-workspace-base
version: 2.0.0
version: 2.1.0
description: "A base Azure TRE workspace"
dockerfile: Dockerfile.tmpl
registry: azuretre
Expand Down Expand Up @@ -126,6 +126,14 @@ parameters:
type: string
default: "GRS"
description: "The redundancy option for the storage account in the workspace: GRS (Geo-Redundant Storage) or ZRS (Zone-Redundant Storage)."
- name: enable_airlock_malware_scanning
type: boolean
default: false
description: "Enable malware scanning on the workspace storage account"
- name: airlock_malware_scan_result_topic_name
type: string
default: ""
description: "The name of the topic to publish scan results to"
Comment thread
SiobhanBaynes marked this conversation as resolved.

outputs:
- name: app_role_id_workspace_owner
Expand Down Expand Up @@ -196,6 +204,8 @@ install:
enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption }
key_store_id: ${ bundle.parameters.key_store_id }
storage_account_redundancy: ${ bundle.parameters.storage_account_redundancy }
enable_airlock_malware_scanning: ${ bundle.parameters.enable_airlock_malware_scanning }
airlock_malware_scan_result_topic_name: ${ bundle.parameters.airlock_malware_scan_result_topic_name }
backendConfig:
use_azuread_auth: "true"
use_oidc: "true"
Expand Down Expand Up @@ -241,6 +251,8 @@ upgrade:
enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption }
key_store_id: ${ bundle.parameters.key_store_id }
storage_account_redundancy: ${ bundle.parameters.storage_account_redundancy }
enable_airlock_malware_scanning: ${ bundle.parameters.enable_airlock_malware_scanning }
airlock_malware_scan_result_topic_name: ${ bundle.parameters.airlock_malware_scan_result_topic_name }
backendConfig:
use_azuread_auth: "true"
use_oidc: "true"
Expand Down Expand Up @@ -268,17 +280,17 @@ upgrade:
- login
flags:
service-principal: ""
username: '${ bundle.credentials.auth_client_id }'
password: '${ bundle.credentials.auth_client_secret }'
tenant: '${ bundle.credentials.auth_tenant_id }'
username: "${ bundle.credentials.auth_client_id }"
password: "${ bundle.credentials.auth_client_secret }"
tenant: "${ bundle.credentials.auth_tenant_id }"
allow-no-subscriptions: ""
- exec:
description: "Update workspace app redirect urls"
command: ./update_redirect_urls.sh
flags:
workspace-api-client-id: '${ bundle.parameters.client_id }'
aad-redirect-uris-b64: '${ bundle.parameters.aad_redirect_uris }'
register-aad-application: '${ bundle.parameters.register_aad_application }'
workspace-api-client-id: "${ bundle.parameters.client_id }"
aad-redirect-uris-b64: "${ bundle.parameters.aad_redirect_uris }"
register-aad-application: "${ bundle.parameters.register_aad_application }"

uninstall:
- terraform:
Expand Down Expand Up @@ -309,6 +321,8 @@ uninstall:
enable_cmk_encryption: ${ bundle.parameters.enable_cmk_encryption }
key_store_id: ${ bundle.parameters.key_store_id }
storage_account_redundancy: ${ bundle.parameters.storage_account_redundancy }
enable_airlock_malware_scanning: ${ bundle.parameters.enable_airlock_malware_scanning }
airlock_malware_scan_result_topic_name: ${ bundle.parameters.airlock_malware_scan_result_topic_name }
backendConfig:
use_azuread_auth: "true"
use_oidc: "true"
Expand Down
6 changes: 6 additions & 0 deletions templates/workspaces/base/terraform/airlock/data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@ data "azurerm_servicebus_topic" "blob_created" {
resource_group_name = local.core_resource_group_name
namespace_name = data.azurerm_servicebus_namespace.airlock_sb.name
}

data "azurerm_eventgrid_topic" "scan_result" {
count = var.enable_airlock_malware_scanning ? 1 : 0
name = local.airlock_malware_scan_result_topic_name
resource_group_name = local.core_resource_group_name
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ resource "azurerm_role_assignment" "servicebus_sender_export_blocked_blob_create
]
}


## Subscriptions
resource "azurerm_eventgrid_event_subscription" "import_approved_blob_created" {
name = "import-approved-blob-created-${var.short_workspace_id}"
Expand Down
3 changes: 2 additions & 1 deletion templates/workspaces/base/terraform/airlock/locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ locals {
export_rejected_sys_topic_name = "evgt-airlock-export-rejected-${local.workspace_resource_name_suffix}"
export_blocked_sys_topic_name = "evgt-airlock-export-blocked-${local.workspace_resource_name_suffix}"

blob_created_topic_name = "airlock-blob-created"
blob_created_topic_name = "airlock-blob-created"
airlock_malware_scan_result_topic_name = var.airlock_malware_scan_result_topic_name

# STorage AirLock IMport APProved
import_approved_storage_name = lower(replace("stalimapp${substr(local.workspace_resource_name_suffix, -8, -1)}", "-", ""))
Expand Down
4 changes: 4 additions & 0 deletions templates/workspaces/base/terraform/airlock/providers.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ terraform {
source = "hashicorp/azurerm"
version = ">= 3.117.0"
}
azapi = {
source = "Azure/azapi"
version = ">= 1.15.0"
}
}
}

Expand Down
28 changes: 26 additions & 2 deletions templates/workspaces/base/terraform/airlock/storage_accounts.tf
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ resource "azurerm_storage_account" "sa_export_inprogress" {
shared_access_key_enabled = false
local_user_enabled = false

# Important! we rely on the fact that the blob craeted events are issued when the creation of the blobs are done.
# Important! we rely on the fact that the blob created events are issued when the creation of the blobs are done.
# This is true ONLY when Hierarchical Namespace is DISABLED
is_hns_enabled = false

Expand Down Expand Up @@ -207,7 +207,6 @@ resource "azurerm_storage_account_network_rules" "sa_export_inprogress_rules" {
bypass = ["AzureServices"]
}


resource "azurerm_private_endpoint" "export_inprogress_pe" {
name = "pe-sa-export-ip-blob-${var.short_workspace_id}"
location = var.location
Expand All @@ -230,6 +229,31 @@ resource "azurerm_private_endpoint" "export_inprogress_pe" {
}
}

# Enable Airlock Malware Scanning on Core TRE for Export In-Progress
resource "azapi_resource_action" "enable_defender_for_storage_export" {
count = var.enable_airlock_malware_scanning ? 1 : 0
type = "Microsoft.Security/defenderForStorageSettings@2022-12-01-preview"
resource_id = "${azurerm_storage_account.sa_export_inprogress.id}/providers/Microsoft.Security/defenderForStorageSettings/current"
method = "PUT"

body = jsonencode({
properties = {
isEnabled = true
malwareScanning = {
onUpload = {
isEnabled = true
capGBPerMonth = 5000
Comment thread
SiobhanBaynes marked this conversation as resolved.
},
scanResultsEventGridTopicResourceId = data.azurerm_eventgrid_topic.scan_result[0].id
}
sensitiveDataDiscovery = {
Comment thread
SiobhanBaynes marked this conversation as resolved.
isEnabled = false
}
overrideSubscriptionLevelSettings = true
}
})
}

# 'Rejected' location for export
resource "azurerm_storage_account" "sa_export_rejected" {
name = local.export_rejected_storage_name
Expand Down
6 changes: 6 additions & 0 deletions templates/workspaces/base/terraform/airlock/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,9 @@ variable "encryption_identity_id" {
variable "encryption_key_versionless_id" {
type = string
}
variable "enable_airlock_malware_scanning" {
type = bool
}
variable "airlock_malware_scan_result_topic_name" {
type = string
}
12 changes: 12 additions & 0 deletions templates/workspaces/base/terraform/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,15 @@ variable "storage_account_redundancy" {
default = "GRS"
description = "The redundancy option for the storage account in the workspace: GRS (Geo-Redundant Storage) or ZRS (Zone-Redundant Storage)."
}

variable "enable_airlock_malware_scanning" {
type = bool
default = false
description = "Enable Airlock malware scanning for the workspace"
}

variable "airlock_malware_scan_result_topic_name" {
type = string
description = "The name of the topic to publish scan results to"
default = null
}
30 changes: 16 additions & 14 deletions templates/workspaces/base/terraform/workspace.tf
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,22 @@ module "aad" {
}

module "airlock" {
count = var.enable_airlock ? 1 : 0
source = "./airlock"
location = var.location
tre_id = var.tre_id
tre_workspace_tags = local.tre_workspace_tags
ws_resource_group_name = azurerm_resource_group.ws.name
enable_local_debugging = var.enable_local_debugging
services_subnet_id = module.network.services_subnet_id
short_workspace_id = local.short_workspace_id
airlock_processor_subnet_id = module.network.airlock_processor_subnet_id
arm_environment = var.arm_environment
enable_cmk_encryption = var.enable_cmk_encryption
encryption_key_versionless_id = var.enable_cmk_encryption ? azurerm_key_vault_key.encryption_key[0].versionless_id : null
encryption_identity_id = var.enable_cmk_encryption ? azurerm_user_assigned_identity.encryption_identity[0].id : null
count = var.enable_airlock ? 1 : 0
source = "./airlock"
location = var.location
tre_id = var.tre_id
tre_workspace_tags = local.tre_workspace_tags
ws_resource_group_name = azurerm_resource_group.ws.name
enable_local_debugging = var.enable_local_debugging
services_subnet_id = module.network.services_subnet_id
short_workspace_id = local.short_workspace_id
airlock_processor_subnet_id = module.network.airlock_processor_subnet_id
arm_environment = var.arm_environment
enable_cmk_encryption = var.enable_cmk_encryption
encryption_key_versionless_id = var.enable_cmk_encryption ? azurerm_key_vault_key.encryption_key[0].versionless_id : null
encryption_identity_id = var.enable_cmk_encryption ? azurerm_user_assigned_identity.encryption_identity[0].id : null
enable_airlock_malware_scanning = var.enable_airlock_malware_scanning
airlock_malware_scan_result_topic_name = var.enable_airlock_malware_scanning ? var.airlock_malware_scan_result_topic_name : null
depends_on = [
module.network,
]
Expand Down