Use the Knowledge Base AI to help improve your Cloud Posture

Azure Cosmos DB Accounts Encrypted with Customer-Managed Keys

Trend Vision One™ provides continuous assurance that gives peace of mind for your cloud infrastructure, delivering over 1100 automated best practice checks.

Risk Level: High (not acceptable risk)

Ensure that your Azure Cosmos DB accounts are encrypted using Customer-Managed Keys (CMKs) instead of Microsoft-managed keys (i.e. default keys used by Microsoft Azure for encryption at rest) in order to have a more granular control over your data encryption and decryption process.

Security

Microsoft Azure automatically encrypts Azure Cosmos DB account data at rest. The encryption protects your data and assists in fulfilling your organization's security and compliance requirements. By default, the encryption process uses Microsoft-managed keys, also known as service-managed keys. However, you can bring your own keys (i.e. Customer-Managed Keys) to fully control who can use the encryption keys and access the encrypted data. Using Customer-Managed Keys (CMKs) also allows you to automatically update the key version used for storage encryption whenever a new version is available.


Audit

To determine if your Azure Cosmos DB accounts are using Customer-Managed Keys (CMKs) for encryption, perform the following operations:

Getting the encryption configuration for Azure Cosmos DB accounts using Microsoft Azure Portal is not currently supported.

Using Azure CLI

01 Run account list command (Windows/macOS/Linux) with custom output filters to list the IDs of the cloud subscriptions available in your Azure cloud account:

az account list
	--query '[*].id'

02 The command output should return the requested subscription identifiers (IDs):

[
	"abcdabcd-1234-abcd-1234-abcdabcdabcd",
	"abcd1234-abcd-1234-abcd-abcd1234abcd"
]

03 Run account set command (Windows/macOS/Linux) with the ID of the Azure cloud subscription that you want to examine as the identifier parameter to set the selected subscription to be the current active subscription (the command does not produce an output):

az account set
	--subscription abcdabcd-1234-abcd-1234-abcdabcdabcd

04 Run cosmosdb list command (Windows/macOS/Linux) with custom output filters to list the ID of each Azure Cosmos DB account available in the selected subscription:

az cosmosdb list
	--query '[*].id'

05 The command output should return the requested Azure Cosmos DB account IDs:

[
	"/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.DocumentDB/databaseAccounts/cc-project5-cosmos-database",
	"/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.DocumentDB/databaseAccounts/cc-cosmos-prod-dba-account"
]

06 Run cosmosdb show command (Windows/macOS/Linux) with the ID of the Azure Cosmos DB account that you want to examine as the identifier parameter and custom output filters to determine if encryption at rest using Customer-Managed Keys is enabled for the selected Cosmos DB account:

az cosmosdb show
	--ids "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.DocumentDB/databaseAccounts/cc-project5-cosmos-database"
	--query "{keyVaultKeyUri:keyVaultKeyUri}"

07 The command output should return the URI of the Customer-Managed Key (CMK) used for Cosmos DB account encryption:

{
	"keyVaultKeyUri": null
}

If the cosmosdb show command output returns null for the "keyVaultKeyUri" attribute, as shown in the example above, encryption at rest using Customer-Managed Keys (CMKs) is not enabled for the selected Microsoft Azure Cosmos DB account.

08 Repeat steps no. 6 and 7 for each Azure Cosmos DB account available within the current Azure subscription.

09 Repeat steps no. 3 – 8 for each Azure subscription created in your Microsoft Azure cloud account.

Remediation / Resolution

To enable encryption at rest for existing Azure Cosmos DB accounts using Customer-Managed Keys (CMKs), perform the following operations:

Enabling encryption with Customer-Managed Keys (CMKs) for Azure Cosmos DB accounts using Microsoft Azure Portal is not currently supported.

Using Azure CLI

01 Run account list command (Windows/macOS/Linux) with custom output filters to list the IDs of the cloud subscriptions available in your Azure cloud account:

az account list
	--query '[*].id'

02 The command output should return the requested subscription identifiers (IDs):

[
	"abcdabcd-1234-abcd-1234-abcdabcdabcd",
	"abcd1234-abcd-1234-abcd-abcd1234abcd"
]

03 Run account set command (Windows/macOS/Linux) with the ID of the Azure cloud subscription that you want to access as the identifier parameter to set the selected subscription to be the current active subscription (the command does not produce an output):

az account set
	--subscription abcdabcd-1234-abcd-1234-abcdabcdabcd

04 Run identity create command (OSX/Linux/UNIX) to create a new user-assigned managed identity for your Azure Cosmos DB account, required to access the Azure key vault for using the Customer-Managed Key:

az identity create
	--name cc-project5-user-identity
	--resource-group cloud-shell-storage-westeurope
	--location westeurope
	--query '{id:id,principalId:principalId}'

05 The command output should return the resource ID and the principal ID of the new user-assigned managed identity:

{
	"id": "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourcegroups/cloud-shell-storage-westeurope/providers/Microsoft.ManagedIdentity/userAssignedIdentities/cc-project5-user-identity",
	"principalId": "abcdabcd-abcd-abcd-abcd-abcdabcdabcd"
}

06 Run keyvault create command (Windows/macOS/Linux) to create the Microsoft Azure key vault where the required Customer-Managed Key (CMK) will be placed. Both soft delete and purge protection must be enabled on the new key vault:

az keyvault create
	--name tm-project5-key-vault
	--resource-group cloud-shell-storage-westeurope
	--location westeurope
	--enable-rbac-authorization false
	--enabled-for-deployment true
	--enabled-for-template-deployment true
	--enable-purge-protection true
	--enabled-for-disk-encryption true

07 The command output should return the configuration information available for the new Azure key vault:

{
	"id": "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.KeyVault/vaults/tm-project5-key-vault",
	"location": "westeurope",
	"name": "tm-project5-key-vault",
	"properties": {
		"accessPolicies": [
		{
			"applicationId": null,
			"objectId": "abcdabcd-abcd-abcd-abcd-abcdabcdabcd",
			"permissions": {
			"certificates": [
				"all"
			],
			"keys": [
				"all"
			],
			"secrets": [
				"all"
			],
			"storage": [
				"all"
			]
			},
			"tenantId": "abcdabcd-1234-abcd-1234-abcdabcdabcd"
		}
		],
		"createMode": null,
		"enablePurgeProtection": true,
		"enableRbacAuthorization": false,
		"enableSoftDelete": true,
		"enabledForDeployment": true,
		"enabledForDiskEncryption": true,
		"enabledForTemplateDeployment": true,
		"hsmPoolResourceId": null,
		"networkAcls": null,
		"privateEndpointConnections": null,
		"provisioningState": "Succeeded",
		"publicNetworkAccess": "Enabled",
		"sku": {
			"family": "A",
			"name": "standard"
		},
		"softDeleteRetentionInDays": 30,
		"tenantId": "abcdabcd-1234-abcd-1234-abcdabcdabcd",
		"vaultUri": "https://tm-project5-key-vault.vault.azure.net/"
	},
	"resourceGroup": "cloud-shell-storage-westeurope",
	"systemData": {
		"createdAt": "2024-10-10T17:04:00.983000+00:00",
		"createdBy": "",
		"createdByType": "User",
		"lastModifiedAt": "2024-10-10T17:04:00.983000+00:00",
		"lastModifiedBy": "",
		"lastModifiedByType": "User"
	},
	"tags": {},
	"type": "Microsoft.KeyVault/vaults"
}

08 Run keyvault set-policy command (Windows/macOS/Linux) to assign the right permissions to your new Azure key vault. For the --object-id parameter, use "principalId" value returned in step no. 5:

az keyvault set-policy
	--name tm-project5-key-vault
	--object-id abcdabcd-abcd-abcd-abcd-abcdabcdabcd
	--key-permissions create get recover unwrapKey wrapKey
	--query 'properties.accessPolicies'

09 The command output should return the modified key vault configuration information:

[
	{
		"applicationId": null,
		"objectId": "abcdabcd-abcd-abcd-abcd-abcdabcdabcd",
		"permissions": {
			"certificates": [
				"all"
			],
			"keys": [
				"recover",
				"unwrapKey",
				"get",
				"create",
				"wrapKey"
			],
			"secrets": [
				"all"
			],
			"storage": [
				"all"
			]
		},
		"tenantId": "abcd1234-abcd-1234-abcd-1234abcd1234"
	}
]

10 Run keyvault key create command (Windows/macOS/Linux) to create the Customer-Managed Key (CMK) necessary to encrypt data for your Enterprise Redis cache cluster:

az keyvault key create
	--name tm-project5-cosmos-db-key
	--vault-name tm-project5-key-vault
	--kty RSA
	--size 2048
	--ops decrypt encrypt sign unwrapKey verify wrapKey
	--protection software
	--disabled false
	--query 'key.kid'

11 The command output should return the full URI of the new Customer-Managed Key:

"https://tm-project5-key-vault.vault.azure.net/keys/tm-project5-cosmos-db-key/12345678901234567890123456789012"

12 Run cosmosdb update command (Windows/macOS/Linux) to enable CMK-based encryption for your Microsoft Azure Cosmos DB account. Use the --key-uri parameter to specify the URI of the Customer-Managed Key (CMK) created in the previous steps. The CMK URI format is https://\<key-vault-name\>.vault.azure.net/keys/\<customer-managed-key\>:

az cosmosdb update
	--ids "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.DocumentDB/databaseAccounts/cc-project5-cosmos-database"
	--key-uri "https://tm-project5-key-vault.vault.azure.net/keys/tm-project5-cosmos-db-key"

13 The command output should return the information available for the modified Azure Cosmos DB account:

{
	"analyticalStorageConfiguration": {
		"schemaType": "WellDefined"
	},
	"backupPolicy": {
		"migrationState": null,
		"periodicModeProperties": {
			"backupIntervalInMinutes": 240,
			"backupRetentionIntervalInHours": 8,
			"backupStorageRedundancy": "Local"
		}
	},

	...

	"capabilities": [],
	"capacity": {
		"totalThroughputLimit": 1000
	},
	"connectorOffer": null,
	"consistencyPolicy": {
		"defaultConsistencyLevel": "Session",
		"maxIntervalInSeconds": 5,
		"maxStalenessPrefix": 100
	}
}

14 Repeat steps no. 12 and 13 for each Azure Cosmos DB account that you want to configure, available within the selected subscription.

15 Repeat steps no. 3 – 14 for each Azure subscription created in your Microsoft Azure cloud account.

References

Publication date May 28, 2025