diff --git a/README.md b/README.md index e63c167..9ab064e 100644 --- a/README.md +++ b/README.md @@ -81,28 +81,28 @@ You can use any of these methods to pass parameters: - Deploy the Bicep file using the parameters file: [deploy bicep file with parameters file](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/parameter-files?tabs=Bicep#deploy-bicep-file-with-parameters-file) - Pass the parameters as arguments: [inline-parameters](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/deploy-cli#inline-parameters) -| Parameter name | Required | Description | -|-----------------------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------| -| `defaultSubscriptionId` | yes | Subscription Id of the default Azure Subscription. | -| `falconCID` | yes | CID for the Falcon API. | -| `falconClientId` | yes | Client ID for the Falcon API. | -| `falconClientSecret` | yes | Client secret for the Falcon API. | -| `falconCloudRegion` | no | Falcon cloud region. Defaults to `US-1`. Allowed values are `US-1`, `US-2`, or `EU-1`. | -| `useExistingAppRegistration` | no | Use an existing Application Registration. Defaults to `false`. | -| `grantAppRegistrationAdminConsent` | no | Grant admin consent for Application Registration. Defaults to `true`. | -| `azureClientId` | no | Application Id of an existing Application Registration in Entra ID. Only used with parameter `useExistingAppRegistration`. | +| Parameter name | Required | Description | +|-----------------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------| +| `defaultSubscriptionId` | yes | Subscription Id of the default Azure Subscription. | +| `falconCID` | yes | CID for the Falcon API. | +| `falconClientId` | yes | Client ID for the Falcon API. | +| `falconClientSecret` | yes | Client secret for the Falcon API. | +| `falconCloudRegion` | yes | Falcon cloud region. Allowed values are `US-1`, `US-2`, or `EU-1`. | +| `useExistingAppRegistration` | no | Use an existing Application Registration. Defaults to `false`. | +| `grantAppRegistrationAdminConsent` | no | Grant admin consent for Application Registration. Defaults to `true`. | +| `azureClientId` | no | Application Id of an existing Application Registration in Entra ID. Only used with parameter `useExistingAppRegistration`. | | `azureClientSecret` | no | Application Secret of an existing Application Registration in Entra ID. Only used with parameter `useExistingAppRegistration`. | -| `azurePrincipalId` | no | Principal Id of the Application Registration in Entra ID. Only used with parameter `useExistingAppRegistration`. | -| `azureAccountType` | no | Type of the Azure account to integrate. | -| `location` | no | Location for the resources deployed in this solution. | -| `tags` | no | Tags to be applied to all resources. | -| `deployIOM` | no | Deploy Indicator of Misconfiguration (IOM) integration. Defaults to `true`. | -| `assignAzureSubscriptionPermissions` | no | Assign required permissions on Azure Default Subscription automatically. Defaults to `false`. | -| `assignAzureManagementGroupPermissions` | no | Assign required permissions Azure Management Group automatically. Defaults to `true`. | -| `deployIOA` | no | Deploy Indicator of Attack (IOA) integration. Defaults to `true`. | -| `enableAppInsights` | no | Enable Application Insights for additional logging of Function Apps. Defaults to `false`. | -| `deployActivityLogDiagnosticSettings` | no | Deploy Activity Log Diagnostic Settings. Defaults to `true`. | -| `deployEntraLogDiagnosticSettings` | no | Deploy Entra Log Diagnostic Settings. Defaults to `true`. | +| `azurePrincipalId` | no | Principal Id of the Application Registration in Entra ID. Only used with parameter `useExistingAppRegistration`. | +| `azureAccountType` | no | Type of the Azure account to integrate. | +| `location` | no | Location for the resources deployed in this solution. | +| `tags` | no | Tags to be applied to all resources. | +| `deployIOM` | no | Deploy Indicator of Misconfiguration (IOM) integration. Defaults to `true`. | +| `assignAzureSubscriptionPermissions` | no | Assign required permissions on Azure Default Subscription automatically. Defaults to `false`. | +| `assignAzureManagementGroupPermissions` | no | Assign required permissions Azure Management Group automatically. Defaults to `true`. | +| `deployIOA` | no | Deploy Indicator of Attack (IOA) integration. Defaults to `true`. | +| `enableAppInsights` | no | Enable Application Insights for additional logging of Function Apps. Defaults to `false`. | +| `deployActivityLogDiagnosticSettings` | no | Deploy Activity Log Diagnostic Settings. Defaults to `true`. | +| `deployEntraLogDiagnosticSettings` | no | Deploy Entra Log Diagnostic Settings. Defaults to `true`. | ### Register a single Azure Subscription @@ -160,27 +160,27 @@ You can use any of these methods to pass parameters: - Deploy the Bicep file using the parameters file: [deploy bicep file with parameters file](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/parameter-files?tabs=Bicep#deploy-bicep-file-with-parameters-file) - Pass the parameters as arguments: [inline-parameters](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/deploy-cli#inline-parameters) -| Parameter name | Required | Description | -|---------------------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------| -| `defaultSubscriptionId` | yes | Subscription Id of the default Azure Subscription. | -| `falconCID` | yes | CID for the Falcon API. | -| `falconClientId` | yes | Client ID for the Falcon API. | -| `falconClientSecret` | yes | Client secret for the Falcon API. | -| `falconCloudRegion` | no | Falcon cloud region. Defaults to `US-1`. Allowed values are `US-1`, `US-2`, or `EU-1`. | -| `useExistingAppRegistration` | no | Use an existing Application Registration. Defaults to `false`. | -| `grantAppRegistrationAdminConsent` | no | Grant admin consent for Application Registration. Defaults to `true`. | -| `azureClientId` | no | Application Id of an existing Application Registration in Entra ID. Only used with parameter `useExistingAppRegistration`. | +| Parameter name | Required | Description | +|---------------------------------------|----------|------------------------------------------------------------------------------------------------------------------------------| +| `defaultSubscriptionId` | yes | Subscription Id of the default Azure Subscription. | +| `falconCID` | yes | CID for the Falcon API. | +| `falconClientId` | yes | Client ID for the Falcon API. | +| `falconClientSecret` | yes | Client secret for the Falcon API. | +| `falconCloudRegion` | yes | Falcon cloud region. Allowed values are `US-1`, `US-2`, or `EU-1`. | +| `useExistingAppRegistration` | no | Use an existing Application Registration. Defaults to `false`. | +| `grantAppRegistrationAdminConsent` | no | Grant admin consent for Application Registration. Defaults to `true`. | +| `azureClientId` | no | Application Id of an existing Application Registration in Entra ID. Only used with parameter `useExistingAppRegistration`. | | `azureClientSecret` | no | Application Secret of an existing Application Registration in Entra ID. Only used with parameter `useExistingAppRegistration`. | -| `azurePrincipalId` | no | Principal Id of the Application Registration in Entra ID. Only used with parameter `useExistingAppRegistration`. | -| `azureAccountType` | no | Type of the Azure account to integrate. | -| `location` | no | Location for the resources deployed in this solution. | -| `tags` | no | Tags to be applied to all resources. | -| `deployIOM` | no | Deploy Indicator of Misconfiguration (IOM) integration. Defaults to `true`. | -| `assignAzureSubscriptionPermissions` | no | Assign required permissions on Azure Default Subscription automatically. Defaults to `true`. | -| `deployIOA` | no | Deploy Indicator of Attack (IOA) integration. Defaults to `true`. | -| `enableAppInsights` | no | Enable Application Insights for additional logging of Function Apps. Defaults to `false`. | -| `deployActivityLogDiagnosticSettings` | no | Deploy Activity Log Diagnostic Settings. Defaults to `true`. | -| `deployEntraLogDiagnosticSettings` | no | Deploy Entra Log Diagnostic Settings. Defaults to `true`. | +| `azurePrincipalId` | no | Principal Id of the Application Registration in Entra ID. Only used with parameter `useExistingAppRegistration`. | +| `azureAccountType` | no | Type of the Azure account to integrate. | +| `location` | no | Location for the resources deployed in this solution. | +| `tags` | no | Tags to be applied to all resources. | +| `deployIOM` | no | Deploy Indicator of Misconfiguration (IOM) integration. Defaults to `true`. | +| `assignAzureSubscriptionPermissions` | no | Assign required permissions on Azure Default Subscription automatically. Defaults to `true`. | +| `deployIOA` | no | Deploy Indicator of Attack (IOA) integration. Defaults to `true`. | +| `enableAppInsights` | no | Enable Application Insights for additional logging of Function Apps. Defaults to `false`. | +| `deployActivityLogDiagnosticSettings` | no | Deploy Activity Log Diagnostic Settings. Defaults to `true`. | +| `deployEntraLogDiagnosticSettings` | no | Deploy Entra Log Diagnostic Settings. Defaults to `true`. | ### Troubleshooting diff --git a/cs-deployment-managementGroup.bicep b/cs-deployment-managementGroup.bicep index f740766..858a0c7 100644 --- a/cs-deployment-managementGroup.bicep +++ b/cs-deployment-managementGroup.bicep @@ -43,7 +43,7 @@ param falconClientSecret string 'US-2' 'EU-1' ]) -param falconCloudRegion string = 'US-1' +param falconCloudRegion string @description('Use an existing Application Registration. Defaults to false.') param useExistingAppRegistration bool = false diff --git a/cs-deployment-subscription.bicep b/cs-deployment-subscription.bicep index 9646bb6..18ea9bd 100644 --- a/cs-deployment-subscription.bicep +++ b/cs-deployment-subscription.bicep @@ -43,7 +43,7 @@ param defaultSubscriptionId string 'US-2' 'EU-1' ]) -param falconCloudRegion string = 'US-1' +param falconCloudRegion string @description('Use an existing Application Registration. Defaults to false.') param useExistingAppRegistration bool = false @@ -106,6 +106,7 @@ module iomAzureSubscription 'modules/iom/azureSubscription.bicep' = if (deployIO falconClientId: falconClientId falconClientSecret: falconClientSecret falconCloudRegion: falconCloudRegion + defaultSubscriptionId: defaultSubscriptionId useExistingAppRegistration: useExistingAppRegistration grantAppRegistrationAdminConsent: grantAppRegistrationAdminConsent azureClientId: useExistingAppRegistration ? '' : azureClientId diff --git a/modules/iom/azureManagementGroupRoleAssignment.bicep b/modules/iom/azureManagementGroupRoleAssignment.bicep index 86595c4..7e691b3 100644 --- a/modules/iom/azureManagementGroupRoleAssignment.bicep +++ b/modules/iom/azureManagementGroupRoleAssignment.bicep @@ -13,7 +13,7 @@ param azurePrincipalId string @description('Type of the Principal. Defaults to ServicePrincipal.') param azurePrincipalType string = 'ServicePrincipal' -param customRole object = { +var customRole = { roleName: 'cs-website-reader' roleDescription: 'CrowdStrike custom role to allow read access to App Service and Function.' roleActions: [ diff --git a/modules/iom/azureRoleDefinitionAssignableScope.bicep b/modules/iom/azureRoleDefinitionAssignableScope.bicep new file mode 100644 index 0000000..2f51fc6 --- /dev/null +++ b/modules/iom/azureRoleDefinitionAssignableScope.bicep @@ -0,0 +1,9 @@ +targetScope = 'subscription' + +param customRoleName string + +resource existingCustomRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + name: guid(customRoleName, subscription().id) +} + +output assignableScopes array = existingCustomRoleDefinition.properties.assignableScopes diff --git a/modules/iom/azureSubscription.bicep b/modules/iom/azureSubscription.bicep index a7ce03d..9e2d502 100644 --- a/modules/iom/azureSubscription.bicep +++ b/modules/iom/azureSubscription.bicep @@ -31,6 +31,9 @@ param falconClientId string @secure() param falconClientSecret string +@description('Subscription Id of the default Azure Subscription.') +param defaultSubscriptionId string = subscription().id + @description('Falcon cloud region.') @allowed([ 'US-1' @@ -118,12 +121,27 @@ module azureAppRegistrationUpdate 'azureAppRegistration.bicep' = if (!useExistin ] } +/* Define required permissions at Azure Subscription scope */ +module azureSubscriptionExistingRoleDefinition 'azureSubscriptionExistingRoleDefinition.bicep' = if (assignAzureSubscriptionPermissions && (subscription().subscriptionId != defaultSubscriptionId)) { + name: '${deploymentNamePrefix}-azureSubscriptionExistingRoleDefinition-${deploymentNameSuffix}' + scope: subscription(defaultSubscriptionId) + params: { + subscriptionId: subscription().id + } +} + +/* Define required permissions at Azure Subscription scope */ +module azureSubscriptionRoleDefinition 'azureSubscriptionRoleDefinition.bicep' = if (assignAzureSubscriptionPermissions && (subscription().subscriptionId == defaultSubscriptionId)) { + name: '${deploymentNamePrefix}-azureSubscriptionRoleDefinition-${deploymentNameSuffix}' +} + /* Assign required permissions on Azure Subscription */ module azureSubscriptionRoleAssignment 'azureSubscriptionRoleAssignment.bicep' = if (assignAzureSubscriptionPermissions) { name: '${deploymentNamePrefix}-azureSubscriptionRoleAssignment-${deploymentNameSuffix}' params: { azurePrincipalType: azurePrincipalType azurePrincipalId: useExistingAppRegistration ? azurePrincipalId : azureAppRegistration.outputs.servicePrincipalId + customRoleDefinitionId: subscription().subscriptionId == defaultSubscriptionId ? azureSubscriptionRoleDefinition.outputs.customRoleDefinitionId : azureSubscriptionExistingRoleDefinition.outputs.customRoleDefinitionId } } diff --git a/modules/iom/azureSubscriptionExistingRoleDefinition.bicep b/modules/iom/azureSubscriptionExistingRoleDefinition.bicep new file mode 100644 index 0000000..3356121 --- /dev/null +++ b/modules/iom/azureSubscriptionExistingRoleDefinition.bicep @@ -0,0 +1,45 @@ +targetScope = 'subscription' + +/* + This Bicep template adds the subscription as an assignable scope on the required permissions to enable CrowdStrike + Indicator of Misconfiguration (IOM) + Copyright (c) 2024 CrowdStrike, Inc. +*/ + +@description('Subscription Id of the targeted Azure Subscription.') +param subscriptionId string + +var customRole = { + roleName: 'cs-website-reader' + roleDescription: 'CrowdStrike custom role to allow read access to App Service and Function.' + roleActions: [ + 'Microsoft.Web/sites/Read' + 'Microsoft.Web/sites/config/Read' + 'Microsoft.Web/sites/config/list/Action' + ] +} + +module assignableScope 'azureRoleDefinitionAssignableScope.bicep' = { + name: guid('getAssignableScope',customRole.roleName, subscription().id) + params: { + customRoleName: customRole.roleName + } + } + +resource modifyExistingCustomRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' = { + name: guid(customRole.roleName, subscription().id) + properties: { + assignableScopes: union(assignableScope.outputs.assignableScopes,[subscriptionId]) + description: customRole.roleDescription + permissions: [ + { + actions: customRole.roleActions + notActions: [] + } + ] + roleName: customRole.roleName + type: 'CustomRole' + } +} + +output customRoleDefinitionId string = modifyExistingCustomRoleDefinition.id diff --git a/modules/iom/azureSubscriptionRoleAssignment.bicep b/modules/iom/azureSubscriptionRoleAssignment.bicep index 608c335..35c276f 100644 --- a/modules/iom/azureSubscriptionRoleAssignment.bicep +++ b/modules/iom/azureSubscriptionRoleAssignment.bicep @@ -12,15 +12,7 @@ param azurePrincipalId string @description('Type of the Principal. Defaults to ServicePrincipal.') param azurePrincipalType string = 'ServicePrincipal' -param customRole object = { - roleName: 'cs-website-reader' - roleDescription: 'CrowdStrike custom role to allow read access to App Service and Function.' - roleActions: [ - 'Microsoft.Web/sites/Read' - 'Microsoft.Web/sites/config/Read' - 'Microsoft.Web/sites/config/list/Action' - ] -} +param customRoleDefinitionId string var roleDefinitionIds = [ 'acdd72a7-3385-48ef-bd42-f606fba81ae7' // Reader @@ -29,22 +21,6 @@ var roleDefinitionIds = [ '7f6c6a51-bcf8-42ba-9220-52d62157d7db' // Azure Kubernetes Service RBAC Reader ] -resource customRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' = { - name: guid(customRole.roleName, subscription().id) - properties: { - assignableScopes: [subscription().id] - description: customRole.roleDescription - permissions: [ - { - actions: customRole.roleActions - notActions: [] - } - ] - roleName: customRole.roleName - type: 'CustomRole' - } -} - resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ for roleDefinitionId in roleDefinitionIds: { name: guid(azurePrincipalId, roleDefinitionId, subscription().id) @@ -59,12 +35,12 @@ resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [ resource customRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid( azurePrincipalId, - customRoleDefinition.id, + customRoleDefinitionId, subscription().id ) properties: { - roleDefinitionId: customRoleDefinition.id + roleDefinitionId: customRoleDefinitionId principalId: azurePrincipalId principalType: azurePrincipalType } -} +} \ No newline at end of file diff --git a/modules/iom/azureSubscriptionRoleDefinition.bicep b/modules/iom/azureSubscriptionRoleDefinition.bicep new file mode 100644 index 0000000..4f86c60 --- /dev/null +++ b/modules/iom/azureSubscriptionRoleDefinition.bicep @@ -0,0 +1,35 @@ +targetScope = 'subscription' + +/* + This Bicep template defines the required permissions at Azure Subscription scope to enable CrowdStrike + Indicator of Misconfiguration (IOM) + Copyright (c) 2024 CrowdStrike, Inc. +*/ + +var customRole = { + roleName: 'cs-website-reader' + roleDescription: 'CrowdStrike custom role to allow read access to App Service and Function.' + roleActions: [ + 'Microsoft.Web/sites/Read' + 'Microsoft.Web/sites/config/Read' + 'Microsoft.Web/sites/config/list/Action' + ] +} + +resource customRoleDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' = { + name: guid(customRole.roleName, subscription().id,'test') + properties: { + assignableScopes: [subscription().id] + description: customRole.roleDescription + permissions: [ + { + actions: customRole.roleActions + notActions: [] + } + ] + roleName: customRole.roleName + type: 'CustomRole' + } +} + +output customRoleDefinitionId string = customRoleDefinition.id \ No newline at end of file