Enable Purge Protection for Azure Key Vault with Azure Policy

9 Min. Read

This article will demonstrate how to enable purge protection feature for Azure Key Vault with Azure Policy and ARM template.

Today, a common theme in cloud environments is enforcing organizational standards and adopting cloud governance since day one. And this is very important since it will give you the ability to define policies, processes, and procedures. These policies then dictate what can be done and verify that what does exist is correct. A service from Microsoft called Azure Policy is a great way to make that happen and take corrective action.

Introduction

Azure Policy is a service in Azure that you use to create, assign, and manage policies. These policies enforce different rules and effects over your resources, so those resources stay compliant with your corporate standards and service level agreements. Azure Policy meets this need by continuously evaluating your resources for non-compliance with assigned policies.

Azure Key Vault is a cloud service for securely storing and accessing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, certificates, or cryptographic keys. Key Vault service supports two types of containers: vaults and managed hardware security module(HSM) pools. Vaults support storing software and HSM-backed keys, secrets, and certificates.

Starting on January 2021, Microsoft announced that the Azure key vault’s soft-delete feature will be turned ON for all existing key vaults, as well as the new ones. The soft-delete feature allows you to recover deleted vaults and objects (keys, secrets, and certificates). When enabled, resources marked as deleted are retained for a specified period (default 90 days) and during this time the service provides a mechanism for recovering the deleted object.

Soft delete is by default ON during Key Vault creation with the default retention period of 90 days. The retention policy can be changed from 7 (minimum) to 90 days (maximum) through the Azure Portal during Azure Key Vault creation.

Purge protection is an optional feature of Azure Key Vault which is disabled by default. Purge protection can only be enabled once soft delete is enabled for the key vault. When purge protection is on, a vault or an object in the deleted state cannot be purged until the retention period has passed. Soft-deleted vaults and objects can still be recovered, ensuring that the retention policy will be followed. Please note that the purge protection retention policy uses the same interval as soft delete. Once the period is set, the retention policy interval cannot be changed.

You have a policy in your organization that dictates to enable purge protection on all new and existing Azure Key Vaults within your subscriptions for enhanced security. As you know, a malicious deletion of a key vault can lead to permanent data loss. A malicious insider in your organization can potentially delete and purge key vaults. Purge protection protects you from insider attacks by enforcing a mandatory retention period for soft-deleted key vaults. No one inside your organization or Microsoft will be able to purge your key vaults during the retention period.

If we take a quick look at Azure Security Center as shown in the figure below, we do have already a built-in Policy definition which is based on the default Azure Security Benchmark (V2) that requires having purge protection enabled for Azure key vaults to pass this security recommendation. This recommendation falls under security control (Implement security best practices).

As a side note, Azure Security Center has also a similar recommendation to enable soft delete for Azure key vaults (Key vaults should have soft delete enabled), however, this recommendation is not relevant anymore since soft delete is enabled by default on all key vaults and cannot be disabled.

Key vaults should have purge protection enabled
Key vaults should have purge protection enabled

Key vaults should have purge protection enabled based on this built-in policy, when you deploy a new Key Vault, Azure Security Center will evaluate the configuration and recommends enabling purge protection for enhanced authentication security to protect from a malicious insider in your organization that can potentially delete and purge your key vaults.

However, this policy does not auto-remediate the unhealthy resources, therefore, you should manually remediate them as described in the ‘Remediation steps‘ section, or you can also trigger a logic app to remediate this recommendation. You can also exempt it if needed, but I don’t recommend doing so because it’s categorized as ‘Medium‘ severity.

Once you have invested time and effort in remediating these resources to increase your Secure Score, you want to make sure that it will not decrease by a serious percentage, again. The problem is that the remediation is always done for existing resources, but NOT for new ones. You can think of remediating resources as a reactive versus a proactive approach.

As cybersecurity hygiene (practice), you need to have a solid Azure Governance to ensure that the new resources you deploy will have certain security standards, patterns, and configurations.

To ensure proper governance, we need to use Azure Policy. This will allow us to auto-enable purge protection on newly deployed Azure key vaults, as well as remediating existing resources at scale, so you can make sure your organization’s policy and security requirements are met.

Prerequisites

To follow this article, you need to have the following:

1) An Azure subscription. If you don’t have an Azure subscription, you can create a free one here.

2) At least one Azure Key Vault is deployed in your subscription. You can follow the quick start guide to create a key vault using the Azure portal.

3) You need to have the appropriate permissions to create and manage Azure Policy definitions. The Azure RBAC built-in roles that you can use are Resource Policy Contributor or Security Admin.

4) Last but not least, you need to have the appropriate permissions to assign the Contributor role for the Managed Identity (Application ID) created during the assignment of the policy either on a management group or a subscription, so the policy with “DeployIfNotExists” can remediate and modify your Key Vault settings. Azure Policy creates a managed identity for each assignment but must have details about what roles to grant the managed identity.

If the managed identity is missing roles, an error is displayed during the assignment of the policy or an initiative. Please note that when creating an assignment through the Azure Portal, the role assignments are auto-granted. However, when using PowerShell, you must manually configure the managed identity. More information can be found here.

Assuming you have all the prerequisites in place, take now the following steps:

Purge Protection for Key Vault policy definition

A quick overview of Azure Policy effects. Each policy definition that you create in the Azure Policy has a single effect. That effect determines what happens when the policy rule is evaluated to match. The effects behave differently if they are for a new resource, an updated resource, or an existing resource.

In this example, we need to set and enable purge protection for all new key vaults that will be deployed and on existing key vaults in our environment. For this to work, we need to use the “DeployIfNotExists” policy. To understand how the Azure Policy effect works with the “DeployIfNotExists” policy definition, please check the official documentation from Microsoft here.

Open the Azure Portal, click “All services” and then search for “Policy” and then click on “Definitions” → “+ Policy definition”.

For the “Definition location“, select the location by clicking the ellipsis [] and select either a management group or a subscription.

In the “Name“ field, give a descriptive name for the policy definition such as – “Enable purge protection for Azure Key Vaults” and add a Description.

In the “Category” section, select the appropriate category for this policy. In this example, we will choose “Key Vault” as shown in the figure below.

New Policy Definition
New Policy Definition

For the “POLICY RULE“, paste the following policy definition in JSON format and then click “Save“.

For the “Role definitions“, make sure that the Contributor is selected. The contributor role is required to set and enable managed identity on the resources.

Here is the Policy definition in JSON format:

{
  "mode": "All",
  "policyRule": {
    "if": {
      "allOf": [
        {
          "field": "type",
          "equals": "Microsoft.KeyVault/vaults"
        },
        {
          "not": {
            "field": "Microsoft.KeyVault/vaults/createMode",
            "equals": "recover"
          }
        },
        {
          "field": "Microsoft.KeyVault/vaults/enableSoftDelete",
          "equals": "true"
        },
        {
          "field": "Microsoft.KeyVault/vaults/enablePurgeProtection",
          "exists": "false"
        }
      ]
    },
    "then": {
      "effect": "[parameters('effect')]",
      "details": {
        "type": "Microsoft.KeyVault/vaults",
        "existenceCondition": {
          "field": "Microsoft.KeyVault/vaults/enablePurgeProtection",
          "equals": "true"
        },
        "roleDefinitionIds": [
          "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
        ],
        "deployment": {
          "properties": {
            "mode": "incremental",
            "parameters": {
              "keyVaultName": {
                "value": "[field('name')]"
              },
              "location": {
                "value": "[field('location')]"
              },
              "skuName": {
                "value": "[field('Microsoft.KeyVault/vaults/sku.name')]"
              },
              "tenantId": {
                "value": "[field('Microsoft.KeyVault/vaults/tenantId')]"
              },
              "accessPolicies": {
                "value": "[field('Microsoft.KeyVault/vaults/accessPolicies')]"
              }
            },
            "template": {
              "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
              "contentVersion": "1.0.0.0",
              "parameters": {
                "keyVaultName": {
                  "type": "string"
                },
                "location": {
                  "type": "string"
                },
                "skuName": {
                  "type": "string"
                },
                "tenantId": {
                  "type": "string"
                },
                "accessPolicies": {
                  "type": "array"
                }
              },
              "variables": {},
              "resources": [
                {
                  "type": "Microsoft.KeyVault/vaults",
                  "apiVersion": "2021-06-01-preview",
                  "name": "[parameters('keyVaultName')]",
                  "location": "[parameters('location')]",
                  "properties": {
                    "sku": {
                      "name": "[parameters('skuName')]",
                      "family": "A"
                    },
                    "tenantId": "[parameters('tenantId')]",
                    "accessPolicies": "[parameters('accessPolicies')]",
                    "enablePurgeProtection": "true"
                  }
                }
              ]
            }
          }
        }
      }
    }
  },
  "parameters": {
    "effect": {
      "type": "String",
      "metadata": {
        "displayName": "Effect",
        "description": "Enable or disable the execution of the policy"
      },
      "allowedValues": [
        "DeployIfNotExists",
        "Disabled"
      ],
      "defaultValue": "DeployIfNotExists"
    }
  }
}

In this custom policy, I am looking for all Key Vaults with soft delete enables, and then I am checking if the “enablePurgeProtection” exists.

The ExistenceCondition option in the template above is super useful for the Azure key vault that has already purge protection enabled. If this condition is true, the policy definition will skip the deployment defined in the “DeployIfNotExists” section.

To learn more about the ExistenceCondition option for the “DeployIfNotExists” properties, please check the official documentation here.

To update and enable purge protection through the ARM template, you must specify the SKU (Standard or Premium) including the family type “A“, the tenant Id, and the access policies. In this example, I am getting all the existing parameters for the deployed key vault and then enable purge protection by updating the value to “True“.

Assign Custom Policy definition

To assign the custom policy definition, take the following steps:

If you want to automate the deployment and assignment of Azure Policies via Azure DevOps instead of using the Azure Portal, then please check the following step-by-step guide.

Open the Azure Portal, click “All services” and then search for “Policy” and then click on “Assignments”. An assignment is a policy that has been assigned to take place within a specific scope.

Select “Assign policy” from the top of the “Policy | Assignments” page.

On the “Assign Policy” page, select the Scope by clicking the ellipsis [] and select either a management group or subscription. You can optionally select a resource group if you want. A scope determines what resources or grouping of resources the policy assignment gets enforced on. Then click Select at the bottom of the Scope page.

Select the Policy definition ellipsis [] to open the list of available definitions. Choose the custom policy that we created in the previous step. The Policy enforcement is Enabled by default. Click Next to continue.

On the Parameters page, specify the parameters for this policy assignment (DeployIfNotExists or Disabled). The default value is set to “DeployIfNotExists“, you can disable the effect of this policy later on by setting the effect to “Disabled“. Click Next to continue.

Assign Policy - DeployIfNotExists
Assign Policy – DeployIfNotExists

In the Remediation page, by default “Create a Managed Identity” is selected for you because existing resources can be updated via a remediation task after the policy is assigned only. Choose the default location for the “Managed Identity“, this is required because policies with the “deployIfNotExists” and “Modify” effect types need the ability to modify resources and edit the configuration on existing resources respectively. To do this, a managed identity will be created automatically for each policy assignment. This identity will also be given the “Contributor” permissions on the scope that you have selected. Click Next to continue.

On the Non-compliance messages page, set the desired message (e.g. Managed identity should be enabled for enhanced authentication security). Then click the “Review + create” button.

Finally, click “Create” to create the assignment.

Verify purge protection enabled on key vault

To verify that the custom policy is deployed successfully, you need to wait for at least 30 minutes after a resource has been created or updated. The policy won’t be triggered immediately, this is by design. To trigger the policy compliance scan manually (immediately), open the cloud shell and run the following command:

$job = Start-AzPolicyComplianceScan -AsJob
$job | ft -AutoSize

The scan job will run in the background as shown in the figure below.

Trigger Azure Policy Compliance Evaluation Manually
Trigger Azure Policy Compliance Evaluation Manually

If you want to check Azure Policy compliance status and remediate non-compliant resources via Azure DevOps Pipelines, then please check the following step-by-step guide.

Behind the scene, Azure Policy will create a Remediation task as shown in the figure below. To remediate existing resources, select the desired policy and then click on the “Remediate” button.

Policy Remediation - Enable Purge Protection for Azure Key Vault
Policy Remediation – Enable Purge Protection for Azure Key Vault

Please note that during an evaluation cycle, the policy definition with a “DeployIfNotExists” effect that matches resources is marked as non-compliant only, but no action is taken on that resource. For this reason, the remediation task was created when you assign the policy definition as described in the previous section.

Open the Azure Portal, click “All services” and then search for “Policy” and then click on “Remediation”. In the Policy | Remediation page, select the Remediation tasks tab, and check the status of the auto-remediation task. It’s completed successfully without any error as shown in the figure below.

Azure Policy - Remediation tasks
Azure Policy – Remediation tasks

If we look at the Key Vault resource under Settings| Properties, we can see that the “Purge protection” status is Enabled.

Azure Key Vault - Purge protection
Azure Key Vault – Purge protection

That’s it there you have it!

Summary

In this article, we showed you how to enable the purge protection feature for Azure Key Vault with Azure Policy and ARM template, so you can make sure your organization’s policy and security requirements are met.

Azure Policies are becoming increasingly popular, as they provide a wide range of management capabilities over Azure resources. Not only do they allow us to enforce policy rules to control Azure resources, but they can also enable us to automatically evaluate compliance and remediate non-compliant resources.

To learn more about auditing publicly accessible Azure App Services with Azure Policy, please check the following step-by-step guide.

To learn more about auditing subnets that do not have Network Security Group (NSG) associated, please check the following step-by-step guide.

To learn more about enabling Managed Identity for Web App with Azure Policy, please check the following step-by-step guide.

__
Thank you for reading my blog.

If you have any questions or feedback, please leave a comment.

-Charbel Nemnom-

Related Posts

Previous

Enable Managed Identity for Web App with Azure Policy

Restore Selective Disk for Azure Virtual Machines with Azure Backup

Next

Let me know what you think, or ask a question...

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe to Stay in Touch

Never miss out on your favorite posts and our latest announcements!

The content of this website is copyrighted from being plagiarized!

You can copy from the 'Code Blocks' in 'Black' by selecting the Code.

Please send your feedback to the author using this form for any 'Code' you like.

Thank you for visiting!