Credentials and secrets should be stored in a secure environment and not directly in an Azure Logic App or script. Azure provides the Key Vault service, which allows to store such secrets in a secure and controllable way. See how this works here.
What is a secret?
The Microsoft documentation of Azure Key Vault describes secrets follows: "A secret is anything that you want to tightly control access to, such as API keys, passwords, certificates, or cryptographic keys." at Azure Key Vault basic concepts and at Azure Key Vault security. So you want to store ALL secrets in a safe location, in a Key Vault, and access them from other services. This can be done within Azure resources with a Managed Identity (see below). In this article we will focus on using an Azure Key Vault and storing such secrets and accessing them later in this step-by-step guide.
Sample Logic App: GetManager with Microsoft Graph
The following Logic App GetManager reads the manager of a user from Azure AD using Microsoft Graph. The HTTP trigger requests a userid and looks up the manager of the given user. The Logic App is using an HTTP call against the Graph endpoint https://graph.microsoft.com/v1.0/users with a userid. This HTTP Graph request needs to authenticate against Azure AD and needs have the required permission to do so. Here we perform this with an app 98a18659... that we have pre-registered and that has the Graph app permission User.Read.All assigned and consented by an Admin. You can find more information about apps at Quickstart: Register an application with the Microsoft identity platform and more about Microsoft Graph at aka.ms/graph. Then, the manger is returned with some default properties, like userPrincipalName, jobTitle, etc. Here is the complete Logic App as a screenshot. If you are interested, you can get the Logic App here.
To make it short: We're using a secret here that isn't meant to be part of the Logic App, but is stored securely in a central vault.
The relevant part here is: For authentication, we are using the following parameters with a sensitive secret. Note: You need to replace your Tenant, Client ID, and Secret with your own tenant id and app data. The values here are for this demo only.
Authentication type: Active Directory OAuth
Tenant: f89d8982... (your Tenant-Id)
Client ID: 98a18659... (your App-Id)
Credential Type: Secret
Secret: 65M8Q... (your Secret)
After the Graph-request, we return the body object to the caller (see the result at the end). So, now we want to replace the secret by using an Azure Key Vault.
Enhance security with a Key Vault
First, we create a new Azure Key Vault Safe101 in the same region as our Logic App as described at Quickstart: Create a key vault using the Azure portal.
In the newly generated Key Vault, we open the Secrets menu and click on the Generate/Import in the top menu. We leave the Upload options set to manual, add a name, like "secret", and paste in the Value from our app (it starts with 65M8Q... here). Then, we click Create.
Optionally, you can specify a date from when to when the key should be valid. The key is generated.
Besides the secure and central management, Azure Key Vault provides versioning. So it´s easy to replace an old key with a new one in one central storage. All apps accessing the key will get the new key values then. You can use the Key Vault endpoint from any app, and so on. See more at Azure Key Vault.
How to access the Key Vault
Non-related Azure resources need to authenticate. In our sample, we need to assign an authentication method to our Logic App that has permissions to read from the Key Vault. We could use a user account, or better Azure Managed Identities that are available for exactly that purpose. See more about the many benefits at What are managed identities for Azure resources?
They come in two flavors:
- System-assigned: Tied to the lifecycle of that service instance. Only that Azure resource can use this identity to request tokens from Azure AD.
- User-assigned: Managed identity as a standalone Azure resource, separately from the resources that use it. Assign it to one or more instances of an Azure service
Depending on the use case, we can generate and use a System-assigned, or a User-assigned identity. Here, we have only one Logic App. So, we go for the System-assigned identity (we do not need to manage this identity ourselves).
We return to the Logic App GetManager, open Identity, System assigned, click on the Status On. Save the configuration as here.
Then, confirm the following dialog. This generates an automatically managed App in Azure AD we can configure to access to the Key Vault.
Additionally, we could assign an Azure role to that app (see the screenshot below). This makes sense, if we want to use that app to access or to manage other resources in the Azure subscription, e.g. a Virtual Machine, a Virtual Network, an App Service, or similar resources.
In our sample, we do not require any access to other Azure resources (except the Key Vault that has to be configured differently). That´s our next step.
Note: If you remove a Managed Identity from an Azure resource, and you recreate it, you get a new Managed Identity (which is in fact, only a GUID with an app behind). The same is valid for a User assigned Managed Identity. You can also follow the steps at Authenticate access to Azure resources with managed identities in Azure Logic Apps.
Allow access for the Managed Identity in Key Vault
Now, we return to the Key Vault Safe101. We open the Access policies menu, and click on Add Access Policy as here.
If we only want to read (and list) secrets, we can configure the access policy with Key permissions like here. We define, what access the managed identity shall get (steps 3 and 4). Then, we click on the None selected link below Select principal to select our Managed Identity.
Now, we search for the name of the Logic App (or the Object Id, which starts with e71ab3cc... here). In our case, we find two GetManager* items. The first is our Logic App identity, while the second GetManagerApp is the app I created before to access the Microsoft Graph. Here, we use the first app which IS our Managed Identity app. In case you are not sure, search for the Object Id. This returns exactly the managed identity app.
The next step is to validate the managed identity app (we see the Object Id e71ab3cc...) and to click Add. The principal shows our (Logic App) GetManager app.
Now, do not forget to click the Save button: "Please click the 'Save' button to commit your changes." (This is a task I often forget, forcing me to reconfigure the policy.)
Only now is this policy valid. We see the policy GetManager app has been added to Safe101.
We are done in our Key Vault.
Use the Key Vault in the Logic App
Back to our Logic App GetManager where we want to use that Managed Identity. We open the designer, and add an action right after the HTTP trigger. We search for "Key Vault", and select the Get secret method as here.
Now, do NOT sign in (we do not want to authenticate with a user connection), but click on the Connect with managed identity (preview) link under the prominent button.
We add a name for the connection (I am using the same name of the Key Vault Safe101 here), fill in the name of the Key Vault, and select System-assigned managed identity. (I guess, after the preview phase of that connector, this could be more convenient in future with a dropdown for the Vault name?). Click Create.
The connection for the Logic App is created. If the access policy works correctly, we can now select the (one and only) key named "secret" we have created in Safe101.
As last step, we just replace the hardcoded secret value in our HTTP action with the result from our Get secret action. We select the value property from the Key Vault endpoint result, as here.
The Secret property is now filled by the looked up value via the managed identity from Safe101. When we switch to the the code view only from curiosity, the property is filled with the lookup action value:
"secret": "@body('Get_secret')?['value']", ...
In real life, every secret should be protected like this.
That´s it. We save the Logic app and try it out.
Test the functionality
Here, we are using Postman to try the Logic App GetManager and call the endpoint with a userid from that organization. As we see, we get the manager "Patti" back from Azure AD.
Hooray, we get a result. This means, the authentication with our Managed Identity from Key Vault works.
Tip: Obscure secrets in runs
To further secure secrets, I recommend to open the Key Vault action settings...
...and set the Secure Outputs switch from Off (default) to On. Confirm the settings with Done.
We can also do that for inputs. The future runs will not show any secret data due to the security settings. Secrets will not be shown to the user.
This is not a strong protection as it only obfuscates the data, but it is good practice against unwanted observers. See more at Secure access and data in Azure Logic Apps and at Secure data in run history by using obfuscation.
Using Azure Key Vault makes it easy to create and control any secrets to encrypt your sensitive data. A Key Vault allows to centralize the storage of application secrets and to control their distribution. As mentioned above, every secret like configuration passwords, connection strings, certificates, etc. should be protected like this. See more at About Azure Key Vault.
I hope this article inspires you to use Azure Key Vault in all your Azure services.