Highlight

Managing application account credentials is just another thing to worry for application developers; especially in public cloud. Learn what is Managed Identity for Azure Services and how does it solve this problem.

Intro

Cloud is all about decomposition of application architecture. Usually more components mean more resilient, more scalable and more cost-effective solution. But this also poses new challenges that previously developers and architects didn’t even need to worry about.

Cross-Service Authentication in Azure

Most cross-service integrations in Azure, are done either via secret keys or token exchange. Token exchange is much better approach because it is done using Azure AD. Thanks to this developers have much better control over security, lifecycle and permissions of their applications. Azure AD allows creation of something called service principal, which in layman terms is simply application user.

Any kind of user in Azure, regardless of its type is called identity. It’s important to remember this, because identity is word very often mentioned in the documentation and in Azure Portal. Typical user consists of Client ID (consider this as username) and Client Secret or Certificate (consider this a password). Any service presenting a set of those credentials can retrieve a token from Azure Active Directory which can be used to communicate with other services in Azure.

Terminology

When it comes to entire topic of Identity and security in Azure there are few terms and a lot of aliases. There is no other way than just simply learning them.

So, in short.

Service Principal - application account (technical user).

- application account (technical user). Identity - a service or user in Azure AD. Often used as synonym for service principal.

- a service or user in Azure AD. Often used as synonym for service principal. Client ID - a globally unique identifier generated for each application and service principal during creation.

- a globally unique identifier generated for each application and service principal during creation. Application ID - synonym for Client ID.

- synonym for Client ID. Managed Service Identity (MSI) - this is old name for what is called right now Managed Identities. Large amount of documentation still is referring to this name.

The simplest design of an application using token authentication looks like this.

To explain the process here

Service A send the request to Azure AD with Application Credentials to get the token to call Service B Azure AD validates the Application Credentials and returns Token on successful authentication Service A send the request to Service B with Token in authorization headers Service B send the request to Azure AD with Token verify the token Azure AD validates the Token and returns validation response Service B responds to Service A

This is good. This is how it should work in well-designed authentication in Azure. But there is a catch in here.

How does Service A store Application Credentials?

There is couple of ways Service A can storage credentials. Most common practice to this date is, storing credentials in configuration file, database or environment variables. As anyone can imagine, this isn’t very the best practice because anyone who has access to environment also has access to credentials.

What about KeyVault?

Managed Identity

Here comes managed identity to save the day. Managed Identities is a feature of Azure AD which automatically creates service principal that is tied with the Azure service itself. This identity is automatically also managed by Azure AD and once service is removed the principal will be too. Great part about this isn’t really the management of that identity but that applications hosted on those services can generate tokens using this identity without a need to provide any credentials.

How is this secure?

It is secure because only application hosted on that service which has managed identity enabled will be able to generate tokens.

How Managed Identity works in detail

In classic approach getting token required applications to send request to login.onmicrosoft.com OAuth endpoint. When doing so application has to supply identity credentials and URL of the service that the token will be used for. With managed identity this is much simpler.

Managed Identity principle is always the same, but the usage and implementation is different across different Azure services. Take app service for example.

App Service

When Managed identity is registered on App Service few things happen.

First of all, a local REST endpoint is registered which is used to retrieve tokens. This endpoint can be only called locally and required secret key from environment variables. Endpoint is located as environment variable called MSI_ENDPOINT http://127.0.0.1:41922/MSI/token/ And secret for this endpoint is environment variable called MSI_SECRET BDCF130B80894D398D9716C10C7C419E Azure Identity (Service Principal) is created in Azure AD which is tied to this service. This identity is automatically managed by Azure AD.

Requesting Token

When MSI is set up requesting token is very simple. Depending on language you use below samples can be used.

C# Example

using Microsoft.Azure.Services.AppAuthentication ; using Microsoft.Azure.KeyVault ; // ... var azureServiceTokenProvider = new AzureServiceTokenProvider (); string accessToken = await azureServiceTokenProvider . GetAccessTokenAsync ( "https://vault.azure.net" ); // OR var kv = new KeyVaultClient ( new KeyVaultClient . AuthenticationCallback ( azureServiceTokenProvider . KeyVaultTokenCallback ) );

PowerShell Example

$apiVersion = "2017-09-01" $resourceURI = "https://vault.azure.net" $tokenAuthURI = $env:MSI_ENDPOINT + "?resource=$resourceURI&api-version=$apiVersion" $tokenResponse = Invoke-RestMethod ` -Method Get ` -Headers @{ "Secret" = "$env:MSI_SECRET" ; "Content-Type" = "application/json" } ` -Uri $tokenAuthURI ` -UseBasicParsing $accessToken = $tokenResponse . access_token

NodeJS Example

const rp = require('request-promise'); const getToken = function(resource, apiver, cb) { let options = { uri: `${process.env["MSI_ENDPOINT"]}/?resource=${resource}&api-version=${apiver}`, headers: { 'Secret': process.env["MSI_SECRET"] } }; rp(options) .then(cb); }

REST Call Example

GET /MSI/token?resource=https://vault.azure.net&api-version=2017-09-01 HTTP / 1.1 Host : localhost:4141 Secret : BDCF130B80894D398D9716C10C7C419E

Setting up example for App Service

To create MSI in app Service use either of following methods.

Portal

Go to Web App (App Service) Search for Identity in the search window on blade list panel Select On option on the blade window Click Save to make the change Once service principal is created following screen should be shown

Azure CLI

az webapp identity assign --name myApp --resource-group myResourceGroup

With output

{ "identityIds" : null , "principalId" : "6009de17-ca37-44d6-b522-5f4de3d2ebdd" , "tenantId" : "1f0fb2d0-9423-4dce-ac05-7f195c4ee405" , "type" : "SystemAssigned" }

Azure PowerShell

Set-AzWebApp -AssignIdentity $true -Name $webappname -ResourceGroupName myResourceGroup

With output

... Identity : Microsoft.Azure.Management.WebSites.Models.ManagedServiceIdentity ...

Azure Resource Manager template

{ "identity" : { "type" : "SystemAssigned" } }

Managed Identity types

There are currently two types on managed identities

System Assigned means that lifecycle of managed identity is automatically and managed by Azure AD.

means that lifecycle of managed identity is automatically and managed by Azure AD. User Assigned allows user to first create Azure AD application/service principal and assign this as managed identity and use it in the same manner. This has few advantages in terms of reuse of applications and their permissions if many services in Azure should share the account and its permissions.

Adding Access to Managed Identity

When managed identity is provisioned it can be found in Azure Portal for many services. This allows for RBAC assignments of Roles.

Go to resource Open Access control (IAM) blade Click on Add Role and select role Select App Service from managed identities section Select identity and click Save

List of services that allow for assignment of RBAC/roles for Managed Identity

Resource Manage r - manage Azure resources

r - manage Azure resources Key Vault - keys, secrets, certificates

- keys, secrets, certificates Data Lake - data in data lake

- data in data lake SQL - data in sql

- data in sql Event Hubs - queue data

- queue data Service Bus - queue data

- queue data Storage blobs and queues - storage and queue data

- storage and queue data Analysis Services - manage AAS data or server properties

Local development

When it comes to local development with managed identity at first it is very confusing. This is one of very good cases for user assigned managed identity.

How in short how it works is.

Because as of Today there is no MSI emulator users need to use Azure CLI. Azure CLI allows to log in as user but also as Azure Service Principal. This is a good use case for User Assigned Managed Identity. When user created its own principal, he/she can log as that principal locally and request tokens using CLI

KeyVault example

az account get-access-token --resource 'https://vault.azure.net'

Why calling local command line isn’t necessarily the most beautiful approach it surely works. But what is great here is that Microsoft SDKs for identity will recognize local development and lack of Managed Identity endpoint and try to call CLI in the background without any code changes. This is huge benefit of using SDKs.

Supported Services

This list is compilation of services which support or partially support managed identities.

Azure Global

Global Azure region means all regions with exception of Azure Germany, Government and China.

Azure Government

Service System assigned User assigned Virtual Machines Preview Preview Virtual Machine Scale Sets Preview Preview App Service Available Not available Blueprints Not available Not available Functions Available Not available Logic Apps Preview Not available Data Factory V2 Not available Not available API Management Available Not available Container Instances Not available Not available Container Registry Tasks Not available Not available

Azure Germany

Service System assigned User assigned Virtual Machines Preview Preview Virtual Machine Scale Sets Preview Preview App Service Available Not available Blueprints Not available Not available Functions Available Not available Logic Apps Not available Not available Data Factory V2 Not available Not available API Management Not available Not available Container Instances Not available Not available Container Registry Tasks Not available Not available

Azure China

China region available via 21Vianet

Service System assigned User assigned Virtual Machines Preview Preview Virtual Machine Scale Sets Preview Preview App Service Available Not available Blueprints Not available Not available Functions Available Not available Logic Apps Preview Not available Data Factory V2 Not available Not available API Management Not available Not available Container Instances Not available Not available Container Registry Tasks Not available Not available

Conclusion

How it all it takes is just review services and start implementing this fantastic feature.

Read more on Identities on Azure documentation for Managed Identity.