Custom security recommendation within Microsoft Defender for Cloud

7 minute read

Microsoft Defender for Cloud offers the option to include custom security recommendations. For custom security recommendations you can think of corporate security guidelines that need to be configured on cloud resources.

Microsoft Defender for Cloud

Microsoft defender for cloud is a combination of already existing tools within the Azure platform. It combines Azure Security Center and Azure Defender. When you would like to read more regarding this rename I would suggest you read this post from Microsoft.

Defender for Cloud is the tool for security posture management and threat protection. It helps you to strengthen the security posture of cloud resources. Defender for Cloud offers the tooling to harden your resources with security recommendations.

Microsoft Defender for Cloud helps streamline the process for meeting regulatory compliance requirements, using the regulatory compliance dashboard. Within this dashboard, there are by default a couple of Industry & regulatory standards already present to help you keep compliance.

On that dashboard, the Azure Security Benchmark is activated by default.

Industry & regulatory standards Azure

The screenshot above shows a couple of regulatory standards that are activated within my environment but you also have the option to add additional standards by choosing the "add more standards" button.

Custom security policy

Within organizations, there are security regulations that need to be followed. In a perfect situation, you want to be able to add these standards and security policies to the Azure platform. This can be done by defining Azure Policies and Azure Policy Initiatives.

Azure Policies

Azure Policies can be defined within bicep and via this way also deployed to the Azure Platform. The snippet below shows an Azure Policy that audits Azure resource groups for specific tags. When a resource group for example has the tag "environment" and the value is set to "production" the resource group should have a resource lock configured.

targetScope = 'managementGroup'

param policyCategory string = 'Custom'
param policySource string = 'Guardrails'

resource bicepAuditResourceLock 'Microsoft.Authorization/policyDefinitions@2021-06-01' = {
  name: 'Audit resource locks based on tags'
  properties: {
    displayName: 'Audit Resource Locks on Resource Groups based on Tags'
    description: 'Audit the use of resource locks on resource groups based on tags used'
    policyType: 'Custom'
    mode: 'All'
    metadata: {
      category: policyCategory
      source: policySource
      version: '0.1.0'
      securityCenter: {
        RemediationDescription: 'The resource group should have a resource locks assigned. Go to the resource group and assign a resource lock or adjust the tag value'
        Severity: 'High'
      }
    }
    parameters: {
      tagName: {
        type: 'String'
        metadata: {
          displayName: 'Tag Name'
          description: 'The Tag name to audit against (i.e. Environment, CostCenter, etc.)'
         }
      }
      tagValue: {
        type: 'String'
        metadata: {
         displayName: 'Tag Value'
         description: 'Value of the tag to audit against (i.e. Prod/UAT/TEST, 12345, etc.)'
        }
       }
    }
    policyRule: {
      if: {
        allOf: [
         {
          field: 'type'
          equals: 'Microsoft.Resources/subscriptions/resourceGroups'
         }
         {
          field: '[concat(\'tags[\', parameters(\'tagName\'), \']\')]'
          equals: '[parameters(\'tagValue\')]'
         }
        ]
       }
       then: {
        effect: 'auditIfNotExists'
        details: {
         type: 'Microsoft.Authorization/locks'
         existenceCondition: {
          field: 'Microsoft.Authorization/locks/level'
          equals: 'CanNotDelete'
         }
        }
       }
    }
  }
}

output policyDefId string = bicepAuditResourceLock.id

Policy initiatives

If there are a lot of policies that need to be configured, these policies can be grouped into policy initiatives. This helps you manage the policies in groups and also check the compliance groups on for example a specific category.

The below snippet shows a bicep file for a policy initiative that contains several policies but also a policy initiative where the policy is linked.

targetScope = 'managementGroup'

param policyCategory string = 'Custom'
param policySource string = 'Guardrails'

//tag parameters
param lockTag string = 'environment'
param lockValue string = 'prd'

module auditPolicy '../audit_hybrid_use_benefit/policy.bicep' = {
  name: 'auditPolicy'
  params: {
    policyCategory: policyCategory
    policySource: policySource
  }
}

module auditResourceLock '../audit_resource_locks_on_resource_groups_based_on_tags/policy.bicep' = {
  name: 'auditResourceLock'
  params: {
    policyCategory: policyCategory
    policySource: policySource
  }
}

module deployResourceLock '../deploy_resource_locks_on_resource_groups_based_on_tags/policy.bicep' = {
  name: 'deployResourceLock'
  params: {
    policyCategory: policyCategory
    policySource: policySource
  }
}

resource corporateInitiative 'Microsoft.Authorization/policySetDefinitions@2021-06-01' = {
  name: 'corporate_initiative'
  properties: {
    policyType: 'Custom'
    displayName: 'Corporate Initiative'
    description: 'Corporate Initiative containing all corporate guardrails'
    metadata: {
      category: policyCategory
      source: policySource
      version: '0.1.0'
    }
    parameters: {}
    policyDefinitions: [
      {
        policyDefinitionId: auditPolicy.outputs.policyDefId
        parameters: {}
      }
      {
        policyDefinitionId: auditResourceLock.outputs.policyDefId
        parameters: {
          tagName: {
            value: lockTag
          }
          tagValue: {
            value: lockValue
          }
        }
      }
      {
        policyDefinitionId: deployResourceLock.outputs.policyDefId
        parameters: {
          tagName: {
            value: lockTag
          }
          tagValue: {
            value: lockValue
          }
        }
      }
    ]
  }
}

Deploy initiative

The initiative shown above can be deployed in a couple of ways. The best approach is to configure an Azure DevOps / GitHub project to manage and deploy the configuration but for a short reference, we will use PowerShell.

Login-AzAccount

bicep build ".\policies\corporate_initiative\initiative.bicep"
$tempFile = ".\policies\corporate_initiative\initiative.json"
$mgId = "mgid"

New-AzManagementGroupDeployment -Name "DeployInitiative" -ManagementGroupId $mgId -TemplateFile $tempFile -Location "WestEurope"

The script deploys the initiative to an Azure Management Group high in the hierarchy. This gives the ability to use the initiative and policies on a lower level as well.

Security Settings

If the platform contains a policy initiative with the security guardrails of the organization, this initiative can be used as a custom security policy within Microsoft Defender for Cloud.

This custom initiative can be configured with the following steps:

  1. Go to "Microsoft Defender for Cloud" within the Azure portal.
  2. Click on "Environment Settings" on the left side of the "Microsoft Defender for Cloud" blade
  3. Click on the correct environment that needs to be configured.
Microsoft Defender for Cloud environment configuration.
  1. Within the environment settings blade make sure the "Security policy" is selected.
  2. On the "Security policy" blade scroll down to "Your custom initiatives" and click on "Add a custom initiative"
  3. On the next blade select your custom initiative and click add.
  4. The policy initiative will be configured and assigned to the environment.

Now that the initiative is configured it takes some time to show up correctly within the portal but when it does you can, for example, find it under "Regulatory compliance".

Custom regulatory compliance

Custom remediation steps

In the OOTB security policies remediation steps can be found to remediate the issues. Within custom policies, there is also an option. Within the policy code, additional data needs to be supplied in the "metadata" property.

resource bicepAuditResourceLock 'Microsoft.Authorization/policyDefinitions@2021-06-01' = {
  name: 'Audit resource locks based on tags'
  properties: {
    displayName: 'Audit Resource Locks on Resource Groups based on Tags'
    description: 'Audit the use of resource locks on resource groups based on tags used'
    policyType: 'Custom'
    mode: 'All'
    metadata: {
      category: policyCategory
      source: policySource
      version: '0.1.0'
      securityCenter: {
        RemediationDescription: 'The resource group should have a resource locks assigned. Go to the resource group and assign a resource lock or adjust the tag value'
        Severity: 'High'
      }
    }

The above snippet is a small section of the policy that contains the "metadata" property. Within the metadata property, there is the option to specify Security Center specific information like the remediation description. Additional options can be found in the security center API reference.