Friday, March 3, 2017

Using Azure Key Vault to Store Configuration Data

There’s lot of ways to store things like username, passwords, urls, etc. for use in CRM code. I’ll be comparing some of those methods in a future blog post, but the more common approaches usually lack 2 things.

First, if you place a value inside some CRM construct and that data changes then you need to track it down in each and every environment and make updates. Maybe doesn’t sound so bad if you’ve only got a couple environments and a little bit of code but as you expand into larger organizations with multiple orgs for Dev, Test, QA, Training, Production, etc. and you start having multiple developers each take their own approach to handling this data, well you can see where this suddenly gets hard to manage.

The second thing is that these usernames and password stored in CRM really aren’t secure. The data isn’t encrypted unless you’re handling it yourself. Sure you can control which users have read access to the plug-in configurations or custom entity records but that probably won’t satisfy that guy from IT security.

One possible solution is to use the Azure Key Vault to store this sensitive information. You can read the finer points for yourself but these are some of the key takeaways:
  • Encrypted storage
  • Centralized management – keep track of all your configuration data in 1 place
  • Logging of key use
  • Simple REST API
Of course there’s some not so good points:
  • Some performance hit – need to make requests outside CRM to get the data
  • Can only retrieve 1 key at a time (unless you’re tricky and combine values)
  • Cost – $.03 per 10,000 operations, not free but not terribly expensive
  • Still need to manage some configuration values inside CRM in order to retrieve data
Still interested?

Getting Set Up

Create a Key Vault in Azure – should be pretty self-explanatory when you click through the portal

image

Create a Secret in the Key Vault

image

Register an application with Azure AD in order to get a Client Id & Client Secret – no different than generating values for CRM Web API use

image

image

Authorize the application – in your Azure AD application you’ll need to give it delegated permissions to Azure Key Vault

image

Allow application access to your secret by created an Access Policy – choose the application you registered as the Principal and give it Secret – Get Access, if you plan on trying to retrieve a Secret based on the name as you’ll see later on, also assign Secret - List Access

SNAGHTML21dd96db

In your Secret, grab the Url as you’ll need it to access it later

image

Finally back in Azure AD under Properties, get your Directory (Tenant) Id as this is also needed later

image

Retrieving A Key Vault Secret In Code (Part 1) Get The Access Token

  1. Use the Client Id, Client Secret, and Tenant Id to request the access token needed for the Key Vault requests
  2. Deserialize the JSON response and extract the token


Retrieving A Key Vault Secret In Code (Part 2) Retrieve A Secret By Url

Earlier in the set up steps you were able to grab a url corresponding to the specific version of the Secret you stored. In cases where you don’t plan on changing the value (revising), using the url should be OK.
  1. Use the url of the Secret and make a HTTP GET request including the access token in the authentication header
  2. Make sure you’re also including the API version at the end of the url
  3. Deserialize the JSON response and extract the value


Retrieving A Key Vault Secret In Code (Part 3) Retrieve A Secret By Name

The problem with using a url is that if you ever want to change the Secret value, you’ll need to make a new version, which in turn creates a new url. I’m sure being able to maintain versions is helpful in many cases but if it’s something like a password, then not so much. The Key Vault API doesn’t have any type of query functionality but it does allow retrieving all versions of a given Secret. So what do we do when a Secret changes and we don’t want to go through CRM environments and update urls? The Key Vault API does provide a means to retrieve all versions of a Secret based on the name. We can do this and then determine which is the most recent, enabled version and use it to retrieve the current value. Admittedly this ends up being at least 3 requests to get the actual value but I guess it’s a small price to pay for security and convenience.
  1. Use the name of the Secret and make a HTTP GET request for the versions including the access token in the authentication header
  2. Max of 25 versions are returned so paging may be required
  3. Deserialize the results and determine which is the most recently created that is also enabled
  4. Use the “id” property (which is the Secret url) to retrieve the Secret value
  5. Deserialize the JSON response and extract the value


In conclusion, this might not be the best solution when performance is your primary concern but it you’re looking for security and manageability then this might be worth taking a look at.

You can download the complete sample here:
https://github.com/jlattimer/CrmAzureKeyVaultExample