Azure Functions is now one of the “go to” tools for implementing integration with other services such as Office 365, Dynamics and Azure SaaS. Or, for those of you who want to develop Webhooks and SPFx (SharePoint Foundation) components using Functions, SharePoint Online is a favorable choice.
Azure Functions have a lot of technical advantages. Firstly, they are offered as “serverless compute” meaning you don’t need to manage the infrastructure. Secondly, they are highly developer-friendly, allowing developers to write code in different languages. It also offers extensive possibilities to scale to meet with busy load demands.
When Azure Functions is utilized for creating and enhancing integrations with other services and or servers, you’ll almost always need to save login information in the configurations of the Function. The login information could be in the form of Account or Password or Client Identifier Secret (Token) combinations. Until recently, securing this kind of sensitive information in the Function’s configuration was a cumbersome task. However, in 2018, Microsoft improved the structure of the Azure Functions, so Azure Key Vault could be used more dextrously. Consequently, this guarantees improved security measures, and more importantly, avoids changing the source code of existing Functions.
The Azure Key Vault is a secure repository to save small encrypted “secrets” such as passwords. The Vault is encrypted using protocols defined by FIPS (Federal Information Processing Standards) 140-2 Level 2 validated HSMs (Hardware Security Modules). Microsoft is not technically able to read or extract the keys, and applications never have direct access to them.
Step 1: Setting the Azure Infrastructure
In order to configure Azure Functions using the Azure Key Vault, follow the below steps:
- Start by creating a new Azure Resource Group or reuse an existing one
- In the Resource Group, create the Storage Account required by the Function App Service
- Add the Function App self
- Then, add the Azure Key Vault Service
- Finally, you will have Azure Resource Group for your Functions with, at least, the service shown in Figure 1
Note: The App Service Plan is created automatically with the App Service.
Step 2: Configure the App Service to be registered in AD
- In the Resource Group, open the App Service
- Go to Platform Features
- Click Identity – in the Networking section
- Switch Status to On and click Save
The purpose of this action is so the App Service gets a Managed Identity assigned, it’s registration in Azure Active Directory (AD), and its enablement to authenticate to cloud services. When the registration is fulfilled, you will get an Object ID, as shown in Figure 2.
In addition, the registration creates two Environment Variables, MSI_ENDPOINT, and MSI_SECRET, containing the identifier that AD requires to access the Application (Figure 3). At any moment, if the Status is reverted to Off, the Environment Variables will be removed.
Step 3: Connect the Key Vault with the Function App
- Go back to the Resource Group, and open the Key Vault
- Click Access Policies
- Then, Add new
- In the Select principal section, search for the name of the Function App – allow a few seconds for this to load.
- Click on the App and use the Select button at the bottom of the page
- In the Add access policy window, go to the Secret permissions box
- Select Get
- Click OK to save changes
- The Access Policies window will now show two policies
- Click Save at the top of the screen
Figure 4. Connecting the Key Vault with the Function App
Step 4: Create the “Secrets” in the Key Vault
The Function App is now registered in AD and the Key Vault is configured to use the registration to maintain the Secrets for the App. A Secret is a dictionary entry consisting of a Name or Value. Both don’t have any restriction, where the Name is the key access to the (secret) Value. This can be configured if the secret has an activation and expiration date, whether it is enabled or not. You are now able to create as many Secrets as you want in the Vault.
- On the Key Vault management window, click Secrets
- Then click on Generate/Import
- Select Manual in the Upload options
- Click Create
- Now the Secret is created in the Vault
- On the list with secrets, click on the Secret
- A window will pop up with the details of the Secret you selected
Note: You can create more versions of the Secret, with their own identifiers, for the same Secret using different passwords or activation times.
- If you click on the version, a new screen appears with its properties, settings, and secret (read-only).
- Save the Secret Identifier somewhere safe because you will need it later, as shown in Figure 6
- Although the Secret can be seen in clear text with the Show Secret Value button, this window will be secured later to be accessible to Administrators only (Administrators know already, in any case, the secret values).
Step 5: Using the Secret in the Function
In the normal life-cycle flow for Functions, developers use external dev-environments first, where passwords are not necessarily discrete because everybody knows them. In this stage, the developers create an App Settings entry in the Function configuration to maintain the password or tokens to access the external systems in just plain text. The App Settings for the Function can be reached from the management window of the Function App, go to Platform features, and then Application settings. In the Application settings section, you can add new entries to make variables that can be grasped from the source code without fast-coding them. For example, the MySharePointPw entry in Figure 7.
The developer and initial tests are now complete, and now the Functions go to the acceptation and production stages. At this stage, you can expect the infrastructure to be secured, so you don’t want to show passwords or access tokens in plain text. This is where the Key Vault can start being utilized. The Azure Administrator creates the Secret in the Key Vault and can allocate the Secret Identifier to the person in charge of the Function App configuration. Then, this person changes the value of the password(s) in the Function App Settings to get access to the production password through the Key Vault. The important point to note here is that everything happens without any change in the source code, therefore meaning you don’t need to recompile and install the Functions again.
To set the Secret in the App Settings, you can use two different syntaxes:
@Microsoft.KeyVault(SecretUri=[SecretIdentifierFoundEarlier])
In the earlier shown example, it will be:
@Microsoft.KeyVault(SecretUri=https://p365funckeyvault.vault.azure.net/secrets/SharePointPassword/ec6d6524a45b41ca8a99d2c885eba08a)
Or you can use the alternative syntax:
@Microsoft.KeyVault(VaultName=[VaultName];SecretName=[SecretName];SecretVersion=[SecretVersionID])
In the earlier shown example, it will be:
Microsoft.KeyVault(VaultName=p365funckeyvault;SecretName=SharePointPassword;SecretVersion=ec6d6524a45b41ca8a99d2c885eba08a)
Step 6: Secure the Key Vault reducing the access surface
The Value of the Secrets are visible in the Vault (see Figure 6), it is important to reduce the access to the Key Vault to only the System Administrators. To do that, open the Key Vault configuration window and go to Access policies. Remove the policies with unauthorized users granted access, and here you can also create new policies for Administrators.
Note: do not remove or change the policy created for the Function App (Step 3) in any case to prevent the Key Vault from losing its connection with the Functions.
Conclusion
You are done. The passwords or tokens to access the external systems are now secured in the Azure Key Vault, and your Azure Functions can source them to be used internally. There are also no source code changes and only the system administrator will get access to the “real”, plain-text values.
You will now have no risks, no hazards, and everything which needs to be secured is protected.
Pingback: Heard at TEC: Mischief Managed – Attacking Azure Managed Identities
Thank you for this article, I have the same problem as Suman.
How to prevent developer getting secured values like passwords.
Thank you for this article, I have the same problem as Suman.
How to prevent developer getting secured values like passwords.
Thank you, very informative; this worked for me
Does this support Azure AD B2C? Which service do return the token if we use AzureServiceTokenProvider? This is AD or AD B2C?
Thanks,
Nice article, when I print the value in the function app, it is returning the value in the clear text format, so developers can see the password when they debug the function app logic, how to protect this?
Article is really helpful and very simple to follow.
This article is awesome, thank you for sharing