Rishabh Ajmera, Software Architect
October 28, 2019
Tired of storing credentials in config files and then encrypting those files, securing passwords at time of deployment and then storing it in a different place, troubleshooting deployed application not working and figuring out that it was human error in typing password in one of those deployment variables? Azure provides a solution by creating a user associated to Application which can be granted access to Resources. Let’s say Good Bye to Passwords for application deployment to Azure!
Create an application and you will have to start thinking about the resources it accesses, granting access to the application over the resources and thus comes the need for managing credentials inside the application and security risk of storing them with the application. In today’s cloud world Microsoft has re-imagined the solution to meet the above needs with Service Principal and Managed Identities.
Let’s try and understand these one at a time.
Conceptually Service Principal is a user in the cloud with user name and Password. ServicePrincipal is granted access over resources in Azure. In the image below, eRetailerDeploymentUser (highlighted at 6) is the ServicePrincipal and eRetailerBus (highlighted at 1) is Azure Servicebus resource. We are adding eRetailerDeploymentUser in “Contributor” Role to Azure servicebus.
One can then use those ServicePrincipal credential to access the resources on which it has access, from code.
Did I just contradict myself? Sort of, just bear with me. It’s the Managed Identities that allow us to work without passwords, however, Managed Identities do have a Service Principal associated with them, hence better to understand Service Principal first.
The need for service principal comes in when we have some setup of the Azure resources to be done programmatically kind of outside of the application/offerings of azure. In such a scenario, we can specify the credentials for Service Principal in a setup utility to do the setup.
Note that such a user is required only during one time setup of the resources in Auzre. Hence post setup the service principal can even be removed and re-added when in future we may need to re-run the setup. Hence there is no security risk if we discard the service principal after every use of the setup utility.
It is identity associated to Application in Azure.This Identity is then given access over resources that it works with. Hence any code running by that authorized application will have access to the resources, without requiring credentials of a specific user. In order to understand the concept of Managed Identity, imagine all of the offerings of Azure being divided into 2 categories.
a. Applications: Examples of applications are Azure App service, Azure functions where we run our code.
b. Resources: Examples of resources are Azure Service Bus, Key Vault, Blobs, Azure Sql, Cosmosdb which our code would access.
There is a list of applications for which Identities can be enabled mentioned under the heading “Azure services that support managed identities for Azure resources” on this Microsoft documentation page. The list of resources that can grant access to these identities is mentioned under the heading “Azure services that support Azure AD authentication” on the same page. Microsoft keeps adding more applications and resources that follow Managed Identity, but most widely used offerings are already available for use.
When these applications enable managed identity, we end up having one managed identity per application.
These are referred to as “System Assigned” Managed Identities. On the resources, we assign Roles to these identities, to grant access.
A further simplification is to have a single managed identity created that can be linked to several applications. These are referred to as “User Assigned” Managed Identities. User Assigned Identities are in preview at the time of writing this blog.
If you are interested in seeing how the above concepts can be used in code, follow along. The code repository is housed in Azure Devops here.
Basic knowledge required for completing each of the exercises is specified in the readme file for that exercise.
We will do a basic setup of an eCommerce application called eRetailer and verify the setup with initiating a use case of Placing an Order. The coding activity can be done in 5 exercises as shown below.
Exercise 1: Service Principal (used in console application) to connect to Azure Service Bus
We create a service principal named eRetailerDeploymentUser. A console application uses credentials of eRetailerDeploymentUser to connect to Azure Servicebus. Service Principal eRetailerDeploymentUser is granted access rights over Azure Service Bus, hence the application does not store/require the Access Key to Azure Service Bus.
Azure Devops folder for Exercise 1 in code repository can be found here.
Exercise 2: Console application (with service principal) accessing Azure Service Bus to create Topology
We continue with console application and using credentials of eRetailerDeploymentUser create the topology in Azure Service Bus.
The topology in Azure Service Bus is created so as to allow sending the “PlaceOrder” command which is handled by subscriber. In next exercises, we will create Azure web app that sends the command and Azure function that handles the command.
Azure Devops folder for Exercise 2 in code repository can be found here.
Exercise 3: Managed Identity (linked to Azure App Service) accessing Azure Service Bus to send “PlaceOrder” command
We create website “eRetailer.Web”, an Azure app service, and enable System-assigned Managed Identity on it. Grant the managed identity access over Azure Service Bus resource created in Exercise 1. This will allow sending “PlaceOrder” command when code is running as part of “eRetailer.Web” Azure app service.
Component of the Sales service will be hosted inside eRetailer.Web, that will send the PlaceOrder command. Service here aligns with the definition as per Service Oriented Architecture i.e. it is a technical authority over specific area of business capability. Service is more abstract and components from the service gets deployed into Azure offerings.
Azure Devops folder for Exercise 3 in code repository can be found here.
Exercise 4: Managed Identity (linked to Azure functions) accessing Azure Vault to retrieve secret for Azure service bus to handle “PlaceOrder” command
Azure functions come into existence only when there is a trigger to handle incoming request. Hence they cannot retrieve the tokens from Azure Service Bus even after managed identity is enabled on them, as can be done with Azure app service. Azure functions require connectionstring/AccessKey to Azure Service Bus. However, Azure functions managed identity can access the Azure Vault, once access is granted to the managed identity over Vault to retrieve the secrets from the Vault, as shown in the following blog. Getting Key Vault Secrets in Azure Functions
Hence, we store the access key of service bus in the Vault as a secret and have Azure function work with the secret to work with the service bus.
Azure Devops folder for Exercise 4 in code repository can be found here.
Exercise 5: Managed Identity (linked to Azure app service) accessing Vault to retrieve a secret from the vault
For demonstrating that Azure App Service can also access the Vault, once Managed Identity linked to it is granted access over Vault.
Azure Devops folder for Exercise 5 in code repository can be found here.
System Assigned Managed Identities provide the security by avoiding use of credentials and just working with access rights. Code required to access the resource varies based on type of application and type of resource that application is trying to access.