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).
  • Identity - 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.
  • Application 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

  1. Service A send the request to Azure AD with Application Credentials to get the token to call Service B
  2. Azure AD validates the Application Credentials and returns Token on successful authentication
  3. Service A send the request to Service B with Token in authorization headers
  4. Service B send the request to Azure AD with Token verify the token
  5. Azure AD validates the Token and returns validation response
  6. 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?

KeyVault is great when there is more than one service that you connect to from your application like a database, web application, external service. It is also great when more than one service principal is used within application or simply when application wants to store a certificate or a secret/key. But application will need to connect to KeyVault first, which will require storing at least single pair of credentials anyway. While KeyVault surely improves credential management in application, it doesn’t solve this basic issue.

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 it comes to App Service below diagram presents high level principle how Managed Identity service works internally.

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

  1. 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.
    1. Endpoint is located as environment variable called MSI_ENDPOINT
       http://127.0.0.1:41922/MSI/token/
    2. And secret for this endpoint is environment variable called MSI_SECRET
       BDCF130B80894D398D9716C10C7C419E
  2. 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

  1. Go to Web App (App Service)
  2. Search for Identity in the search window on blade list panel
  3. Select On option on the blade window
  4. Click Save to make the change
  5. 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.
  • 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.

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

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

  • Resource Manager - manage Azure resources
  • Key Vault - keys, secrets, certificates
  • Data Lake - data in data lake
  • SQL - data in sql
  • Event Hubs - queue data
  • Service Bus - queue data
  • Storage blobs and queues - 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.

Service
(link to Managed Identity docs)
System assignedUser assigned
Available Preview
Available Preview
Available Preview
Preview Preview
Available Preview
Preview Not available
Available Not available
Available Not available
Preview Preview
Not available Not available
Available Preview

Azure Government

ServiceSystem assignedUser 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

ServiceSystem assignedUser 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

ServiceSystem assignedUser 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.

Adam Marczak

Programmer, architect, trainer, blogger, evangelist are just few of many titles. What I really am, is just passionate technology enthusiast. I take great pleasure in learning new technologies and finding ways it can aid people every day. My latest passion is running Azure 4 Everyone YouTube channel where I show that Azure is really for everyone!

Did you enjoy the article?

Share it!

More tagged posts