These Functions replicate bring your own key encryption to Cosmos DB.
You can use these functions to encrypt data using keys secured in Azure Key Vault Secrets and wrapped in Azure Key Service. The keys are placed in redis to reduce Azure Key Vault transactions and can be flushed with another function call. We've built three functions, one to encrypt data and put it into Cosmos, another to get data out of cosmos and decrypt it, and finally a third to flush the Redis cache.
They are all HTTP Trigger Based Functions.
To get started with Azure Key Vault, follow the guide here:
https://docs.microsoft.com/en-us/azure/key-vault/key-vault-get-started
- Set up Azure Key Vault
- Values to be used in
local.settings.json
file:keyVaultPath
: the value ofVault URI
from the key vault properties returned from cmdlet OR if using the Azure Portal, it'll be the value ofDNS Name
from the given Key VaultdataEncryptionKey
: the name of the secret which is used to encrypt your data and is stored in Azure Key Vault in an encrypted statekekIdentifier
: the name of the key which is used to encrypt yourdataEncryptionKey
- Values to be used in
- Register an application with Active Directory
- Values to be used in
local.settings.json
file:applicationId
: the value ofApplication ID
in the App registration portion of Azure Active Directory in the portalapplicationSecret
: the value of the key created in the App registration portion of Azure Active Directory in the portal
- Values to be used in
- Authorize the application to use the key or secret
- Create an Azure Cosmos DB Account
- Values to be used in
local.settings.json
file:cosmosEndpoint
: value ofURI
from Cosmos DB Account >> Keys >> URI on the Azure PortalcosmosPrimaryKey
: value ofPrimary Key
from Azure Cosmos DB Account >> Keys >> Primary Key on the Azure Portal
- Values to be used in
- Create a Azure Redis Cache
- Values to be used in
local.settings.json
file:redisConnectionString
: the value ofPrimary connection string
from Redis Cache >> Access Keys >> Primary connection string on the Azure Portal
- Values to be used in
- To run clone the repo and open in Visual Studio 2017 V 15.5.1 with Azure Tools Installed.
- Restore NuGet Packages (right click Solution)
- Rebuild Project
- Update/Add local.settings.json (refer to the Prerequisites sections for information regarding the values)
The kekIdentifier points to the Key that encrypts or "wraps" your dataEncryptionKey which is stored as a secret in Azure Key Vault in an encrypted state.
Sample local.settings.json:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=storeafunc9520;AccountKey=secretCQ5CNZIjt0D8Vwo6hZClgnulam0bWY1GIHyZ/k3XHcbxX0qFCmIl1VAHLQXjSe0SvjFnirMREMciw==",
"AzureWebJobsDashboard": "DefaultEndpointsProtocol=https;AccountName=storefunc9520;AccountKey=secretfogCQ5CNZIjt0D8Vwo6hZClgnulam0bWY1GIHyZ/k3XHcbxX0qFCmIl1VAHLQXjSe0SvjFnirMREMciw==",
"applicationId": "secret1-a2aa-40ba-a621-c8320026e739",
"applicationSecret": "secretsecretHFXsaCqvExPO2AP3tugkoJIo8cX6N9zVw=",
"keyVaultPath": "https://kvtest.vault.azure.net/",
"cosmosEndpoint": "https://cosmostest.documents.azure.com:443/",
"cosmosPrimaryKey": "secretsecrettQaKtJow34S1LYtQEyEbaW7f7mXpUNs5Xm0mxTkob57V7chtAoVpX5LiuNJdTPkCmtsEL8v3w==",
"dataEncryptionKey": "DEK",
"kekIdentifier": "KeyOne",
"redisConnectionString": "rediscachetest.redis.cache.windows.net:6380,password=secretdf/UcfgXeqqb5IvD6zSLMkG48oiKNzAM+T8g=,ssl=True,abortConnect=False"
}
}
- Start Debugging
- Use Curl/Postman to POST Json to the endpoints. Will be clearly presented in CMD window that pops up. See examples below.
http://localhost:7071/api/EncryptData
{
"databaseName" : "EncryptedData",
"collectionID": "UserInfo",
"userID": "8",
"dataToBeEncrypted": "String of Data To Store"
}
http://localhost:7071/api/GetDecryptedData
{
"databaseName": "EncryptedData",
"collectionID": "UserInfo"
}
http://localhost:7071/api/FlushRedis
{
"no parameters": "required"
}
- The Ability to rotate Key Encryption Keys as a function
- Better exception handling for unfound resources.
-
First:
Package 'Microsoft.AspNet.WebApi.Client 5.2.2' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETStandard,Version=v2.0'. This package may not be fully compatible with your project.
-
Second after removing dependancy on WebApi Client:
System.Private.CoreLib: Could not load file or assembly 'Microsoft.AspNetCore.Mvc.Abstractions, Version=2.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Could not find or load a specific file. (Exception from HRESULT: 0x80131621). System.Private.CoreLib: Could not load file or assembly 'Microsoft.AspNetCore.Mvc.Abstractions, Version=2.0.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
-
Third we found
Microsoft.Azure.KeyVault.Core
on Nuget but that didn't work... even including prerelease.
- No clear story for building/debugging C# Projects in Visual Studio Code, but can be really fun in Node.