Secure services with Azure Key Vault

How can you prevent unintentional exposure of your secrets and certificates when your applications are hosted in the cloud? By using a secret management system you can not only keep those items secret, you also can finetune who has access and when.

In this article I will introduce Azure Key Vault, an Azure service to secure and protect secrets, certificates, and connection strings, so I can protect my PHP application.

In my previous article I explained how to connect an App Service with a MySQL database. In order to establish this connection, I need to provide the connection details as environment variables. Even though this approach works well for small applications with only a few people working on it, it also comes with a few drawbacks:

  1. These connection strings need to be replicated to all services that require that connection;
  2. Rolling over new passwords and certificates requires changes for all services depending on them;
  3. Access control only provided to accounts with the password;
  4. Potential risk of adding the environment variable values to the source code;

To solve these drawbacks and provide centralized secret management for larger organisations, a secret management system is a good solution. Hashicorp Vault, CyberArk Conjur, StrongBox, Knox, and recently 1Password Secrets Automation are really great solutions for managing secrets. Azure Key Vault is the solution I will discuss in this article. It is available with two pricing models: a Standard and a Premium tier. Unless you are a large organisation with high security requirements, the Standard tier will suffice in most use cases. In this article I will use examples that are based on the Standard tier Key Vault.

I will continue from my previous article where I have a very simple PHP application using Azure App Service to host my PHP application and Azure Databases for MySQL to store my data. But instead of using the database connection string as an environment variable, I’m going to use Azure Key Vault to pull in the connection string.

Getting started

In order to use Azure Key Vault, I must set it up in my Resource Group. In Azure Portal I need to add a resource, type in Key Vault, select Microsoft Key Vault, and hit the “Create” button.

Creating an Azure Key Vault resource

A set of screens will guide me through the configuration process. The first screen is the basics where I provide information about the name, location, and pricing tier I want to use for this key vault.

Configuring the basics first

The access policy will be a little bit trickier: here I can provide access to the key vault and by default it is set to a standard vault access policy. But because only our app needs to access the keyvault, I’m going to change it to a role based access policy. With a role based access policy, I can define security principals (one for the administrator and one for the application) that will allow access to this key vault.

Selecting a role based access policy for the key vault

In the network section I can define which network can access my secrets. Since I don’t have specified my own networks, I choose public access. In a next article I explain how to set up different networks and why this is important. For now, I go with public access.

Network section set to public (for now)

In the tag section I give my key vault some meaningful tags which helps me later on to identify the usage of this vault in my billing statements.

Adding tags to my key vault

In the final step I have a chance to review all the settings again before I create my key vault.

Double checking all settings are correct

The creation of a key vault takes a few minutes, just be patient for it to complete.

Deployment of the Key Vault

Adding the connection string as a secret

Once the deployment is finished, I can go to the key vault resource to set things up.

Now the key vault is created and ready for usage

In the previous article I had created my own environment variable called “DB4MYSQL_CONN”, which contained the connection string to the Azure databases for MySQL resource. I will now move this connection string out of my App Service environment and store it into Azure Key Vault.

To achieve this goal, I create a new secret in Key Vault which I will name “db4mysql-conn”.

Creating a secret in Azure Key Vault

Enable Managed Identity for App Service

Now that the secret connection string is created, I need to ensure that my App Service can access this connection string. To do this, I first have to enable managed identity for my php-helloworld-from-azure application. In my app settings on the Identity blade, I turn the Managed Identity flag to on. Now it becomes a managed identity in Azure Active Directory and I can assign roles to it.

Toggling the Identity for my app on

Once the managed identity is activated, I can assign it a role to access my key vault and reads my secrets. I choose “Key Vault Secrets User” as the role for my application.

Role based access as Key Vault Secrets User

Connecting app with vault

Last step is to connect the key vault with my application. I can use the magic token from Microsoft Azure to access my secret. In the configuration settings of my application, I can now use the “@Microsoft.KeyVault()” reference as a replacement for the original connection string.

Using the Azure Reference Magic to connect to my Key Vault Secret

And that should be all. If I check my web application, I see it still is able to connect to my Azure Database for MySQL resource, this time using Azure Key Vault.

Both database still available using the secret connection string from Azure Key Vault

In my next article I will explain how I can mange the SSL certificates for Azure Database for MySQL with Azure Key Vault. This will allow me to use a certificate I manage myself that can also be verified by my application to improve security. See you next time.

Michelangelo
Michelangelo

Passionate PHP developer, architect and community leader with nearly 20 years of experience in developing, modernizing and improving quality of complex PHP applications for enterprise, government, SMB and start-up markets.

Articles: 8

6 Comments

  1. Hi Michelangelo,

    You mention “Last step is to connect the key vault with my application. I can use the magic token from Microsoft Azure to access my secret. In the configuration settings of my application, I can now use the “@Microsoft.KeyVault()” reference as a replacement for the original connection string.”

    Is this a php library or function that you are using? Could you update the update the article with the details of the php code necessary to read the secret from keyvault?

    • Hi @lotaezhao,

      Thank you for your question, which is a good one which requires additional explanation. The “@Microsoft.KeyVault()” string is a special function for Azure Services depicted by the “@“ symbol. This means that the application (who has been given permission to access the key vault) executes this function every time it is requested. The return value of this function is the string that was stored in the key vault.

      This has two advantages:
      1. Your environment variables don’t expose the secret when it is being output in logs or dumps
      2. Your application can still use the same environment variables to execute the function and have a string value in return.

      In my opinion it is a very safe way to keep secrets hidden without making changes to your application.

  2. Hi – Can I just ask.
    On the previous article you had ‘getenv(‘MYSQLCONNSTR_localdb’, true);’ in the code. Are you saying that by making the changes from this article that you replaced that with ‘getenv(‘@Microsoft.KeyVault()’, true);’?

    As a follow up question.

    If you dump the env variables what do you actually see?

    • In this specific situation I used the built-in MySQL database of the App Service without any other Azure services. But you can use Azure Key Vault (or any other secret management system) to safely keep your connection details out of the code base.

      To answer your second question: a dump of $_SERVER values or environment variables will display everything in clear text, including secrets. Always be wary about it and don’t set these environment values for clasified information.

  3. Can you please add php code for “@Microsoft.KeyVault()”, it would be very useful to us.

    • A good suggestion to showcase the interaction between PHP apps and Azure Key Vault. I have currently a project with a requirement to connect securely to Azure Storage Accounts with secrets kept in Azure Key Vault. I think it would serve a good example how both are working brilliantly with PHP applications.

      Thank you for suggesting.

Leave a Reply

Your email address will not be published. Required fields are marked *

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