Reading secrets from KeyVault in your Azure Cloud Service

Screenshot 2019-08-17 at 22.44.40Azure Cloud Service was one of the earliest Platform as a Service offerings by Microsoft Azure. With Cloud Services you can run web applications or run background applications. Since it is a PaaS offering, you dot not need to worry about the issues that comes with IaaS, patching for example and they offer a lot of flexibility. They are not officially deprecated, though Microsoft is pushing for the use of other PaaS offerings. So, if you’re starting to build a new app today you probably don’t want to choose the Azure Cloud Service. You might however, still have a few running in production today. If you do so, then at lease make sure you are reading and using your application secrets in a secure way. This blog will help you do that as it will explain how to read secrets from Azure KeyVault from your Azure Cloud Service! In a previous post I explained how you can create the KeyVault I use in this post.

No Managed Service Identity

You would preferably use a Managed Service Identity to access Azure Key Vault and avoid keeping client Secret key in cloud service configuration. In absence of managed service identities for cloud services, you can use Certificate Credentials for application authentication to help establish application identity and get access to key vault for reading keys, secrets etc.

We first need to create a Service Principal in AD and an App registration. Using a certificate we assign to both this Service Principal and our Cloud Service, we can authenticate with KeyVault as if we are this Service Principal.

Azure DevOps

All of the next steps are part of my pipeline in Azure DevOps. Before we can create the SP we first need to make sure that the service connection we use in Azure DevOps has enough permissions to create a new SP in our Azure AD. Here’s how to do that. In Azure DevOps go to Project Settings, Service connections and find the service connection you will use and click ‘Manage Service principal’. This will open a tab to the App Registration in Azure AD. Go to Api Permissions and add ‘Application.ReadWrite.OwnedBy’ from the ‘Azure Active Directory Graph (1)’. In the end it should look like:

Screenshot 2019-10-18 at 20.59.36

Create the Service Principal

I use the following commands to create the SP and App Registration in an Azure CLI task:

Here are the contents of AppRegistrationKeyVaultPermissionManifest.json. We need to do this to be authorised to call the KeyVault API.

After you run this command your should find your new App registration in Azure AD. If you then go to it’s API Permissions you should something similar to this:

Screenshot 2019-10-18 at 20.57.06

Next, we need the ObjectID and the AppId of the SP we just created. The ObjectID is used later on to give the appropriate Access Policies in KeyVault, the AppId is needed to upload the certificate to the SP in a later step.  Unfortunately, not both are being returned from the create command above so we need to query AD to get them. The following script will do that and store the results in an Azure DevOps variable for later use.

Certificate

Now it’s time to add the certificate to the SP. In this example I will use a Self-Signed certificate which I created using the following command:

In order to export the generated certificate with a private key to a password protected PFX file, you will need its thumbprint. It can be copied from the results of New-SelfSignedCertificate command:

This pfx needs to be uploaded into Azure DevOps as a secure file. Navigate to Pipelines → Library → Secure files and upload the certificate.

Add the ‘Download secure file’-task to your pipeline and select your certificate. We now need to get a base64 string of the certificate since that’s the format in which we can give it to the SP. Here’s a script to do that. It will save the value in an Azure DevOps variable for later use:

Now add another ‘Azure CLI’-task to the pipeline and let it execute the following command tho upload the certificate to the SP:

In yet another ‘Azure CLI’-task we will execute the following commands to upload the certificate to your cloud service:

 

Azure KeyVault Access Policies

The last thing we need to do is give this Service Principal the appropriate access policy in our KeyVault. Just like with the App Service in the previous blog, I’ve just an ARM template to do that:

I use the ”-task to deploy the template. In the ‘Override template variables’ box I enter:

-keyVaultName $(keyVaultName) -objectId $(AADObjectId) -secretsPermissions [“list”,”get”] -tenantId $(tenantId) -location $(location)

Code

We obviously also need some code in our Cloud Service to read the certificate and use it the authenticate with KeyVault and get secrets. Here’s how to do that. Make sure you add the certificate to your workers ServiceDefinition or it will not be installed on the VM that runs your service.

 

You may also like...