Welcome back fellow geeks for the second installment in my series on Azure Managed Identities. In the first post I covered the business problem and the risks Managed Identities address and in this post I’ll be how managed identities are represented in Azure.
Let’s start by walking through the components that make managed identities possible.
The foundational component of any identity is the data store in which the identity lives in. In the case of managed identities, like much of the rest of the identity data for the Microsoft cloud, the data store is Azure Active Directory. For those of you coming from the traditional on-premises environment and who have had experience with your traditional directories such as Active Directory or one of the many flavors of LDAP, Azure Active Directory (Azure AD) is an Identity-as-a-Service which includes a directory component we can think of as a next generation directory. This means it’s designed to be highly scalable, available, and resilient and be provided to you in “as a service” model where a simple management layer sits in front of all the complexities of the compute, network, and storage infrastructure that makes up the directory. There are a whole bunch of other cool features such as modern authentication, contextual authorization, adaptive authentication, and behavioral analytics that come along with the solution so check out the official documentation to learn about those capabilities. If you want to nerd out on the design of that infrastructure you can check out this whitepaper and this article.
It’s worthwhile to take a moment to cover Azure AD’s relationship to Azure. Every resource in Azure is associated with an Azure subscription. An Azure subscription acts as a legal and payment agreement (think type of Azure subscription, pay-as-you-go, Visual Studio, CSP, etc), boundary of scale (think limits to resources you can create in a subscription), and administrative boundary. Each Azure subscription is associated with a single instance of Azure AD. Azure AD acts as the security boundary for an organization’s space in Azure and serves as the identity backend for the Azure subscription. You’ll often hear it referred to as “your tenant” (if you’re not familiar with the general cloud concept of tenancy check out this CSA article).
Azure AD stores lots of different object types including users, groups, and devices. The object type we are interested in for the purposes of managed identity are service principals. Service principals act as the security principals for non-humans (such as applications or Azure resources like a VM) in Azure AD. These service principals are then granted permissions to access resources in Azure by being assigned permissions to Azure resources such as an instance of Azure Key Vault or an Azure Storage account. Service principals are used for a number of purposes beyond just Managed Identities such as identities for custom developed applications or third-party applications.
Given that the service principals can be used for different purposes, it only makes sense that the service principal object type includes an attribute called the serviceprincipaltype. For example, a third-party or custom developed application that is registered with Azure AD uses the service principal type of Application while a managed identity has the value set to ManagedIdentity. Let’s take a look at an example of the serviceprincipaltypes in a tenant.
In my Geek In The Weeds tenant I’ve created a few application identities by registering the applications and I’ve created a few managed identities. Everything else within the tenant is default out of the box. To list the service principals in the directory I used the AzureAD PowerShell module. The cmdlet that can be used to list out the service principals is the Get-AzureADServicePrincipal. By default the cmdlet will only return the 100 results, so you need to set the All parameter to true. Every application, whether it’s Exchange Online or Power BI, it needs an identity in your tenant to interact with it and resources you create that are associated with the tenant. Here are the serviceprincipaltypes in my Geek In The Weeds tenant.
Now we know the security principal used by a Managed Identity is stored in Azure AD and is represented by a service principal object. We also know that service principal objects have different types depending on how they’re being used and the type that represents a managed identity has a type of ManagedIdentity. If we want to know what managed identities exist in our directory, we can use this information to pull a list using the Get-AzureADServicePrincipal.
We’re not done yet! Managed Identities also come in multiple flavors, either system-assigned or user-assigned. System-assigned managed identities are the cooler of the two in that they share the lifecycle of the resource they’re used by. For example, a system-assigned managed identity can be created when an Azure Function is created thus that the identity will be deleted once the Azure VM is deleted. This presents a great option for mitigating the challenge of identity lifecycle management. By Microsoft handling the lifecyle of these identities each resource could potentially have its own identity making it easier to troubleshoot issues with the identity, avoid potential outages caused by modifying the identity, adhering to least privilege and giving the identity only the permissions the resource requires, and cutting back on support requests by developers to info sec for the creation of identities.
Sometimes it may be desirable to share a managed identity amongst multiple Azure resources such as an application running on multiple Azure VMs. This use case calls for the other type of managed identity, user-assigned. These identities do not share the lifecycle of the resources using them.
Let’s take a look at the differences between a service principal object for a user-assigned vs a system-assigned managed identity. Here I ran another Get-AzureADServicePrincipal and limited the results to serviceprincipaltype of ManagedIdentity.
ObjectId : a3e9d372-242e-424b-b97a-135116995d4b ObjectType : ServicePrincipal AccountEnabled : True AlternativeNames : {isExplicit=False, /subscriptions//resourcegroups/managedidentity/providers/Microsoft.Compute/virtualMachines/systemmis} AppId : b7fa9389-XXXX AppRoleAssignmentRequired : False DisplayName : systemmis KeyCredentials : {class KeyCredential { CustomKeyIdentifier: System.Byte[] EndDate: 11/11/2019 12:39:00 AM KeyId: f8e439a8-071b-45e0-9f8e-ac10b058a5fb StartDate: 8/13/2019 12:39:00 AM Type: AsymmetricX509Cert Usage: Verify Value: } } ServicePrincipalNames : {b7fa9389-XXXX, https://identity.azure.net/XXXX} ServicePrincipalType : ManagedIdentity ------------------------------------------------ ObjectId : ac960ac7-ca03-4ac0-a7b8-d458635b293b ObjectType : ServicePrincipal AccountEnabled : True AlternativeNames : {isExplicit=True, /subscriptions//resourcegroups/managedidentity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/testing1234} AppId : fff84e09-XXXX AppRoleAssignmentRequired : False AppRoles : {} DisplayName : testing1234 KeyCredentials : {class KeyCredential { CustomKeyIdentifier: System.Byte[] EndDate: 11/7/2019 1:49:00 AM KeyId: b3c1808d-6778-4004-b23f-4d339ed0a91f StartDate: 8/9/2019 1:49:00 AM Type: AsymmetricX509Cert Usage: Verify Value: } } ServicePrincipalNames : {fff84e09-XXXX, https://identity.azure.net/XXXX} ServicePrincipalType : ManagedIdentity
In the above results we can see that the main difference between the user-assigned (testing1234) and system-assigned (systemmis) is the within the AlternativeNames property. For the system-assigned identity has values of isExplicit set to False and has another value of /subscriptions//resourcegroups/managedidentity/
providers/Microsoft.Compute/virtualMachines/systemmis. Notice the bolded portion specifies this is being used by a virtual machine named systemmis. The user-assigned identity has the isExplicit set to True and another property with the value of /subscriptions//resourcegroups/managedidentity/
providers/Microsoft.ManagedIdentity/userAssignedIdentities/testing1234. Here we can see the identity is an “explicit” managed identity and is not directly linked to an Azure resource.
This difference gives us the ability to quickly report on the number of system-assigned and user-assigned managed identities in a tenant by using the following command.
Get-AzureADServicePrincipal -All $True | Where-Object AlternativeNames -like “isExplicit=True*”
True would give us user-assigned and False would give us system-assigned. Neat right?
Let’s summarize what we’ve learned:
- An object in Azure Active Directory is created for each managed identity and represents its security principal
- The type of object created is a service principal
- There are multiple service principal types and the one used by a Managed Identity is called ManagedIdentity
- There are two types of managed identities, user-assigned and system-assigned
- System-assigned managed identities share the lifecycle of the resource they are associated with while user-assigned managed identities are created separately from the resource, do not share the resource lifecycle, and can be used across multiple resources
- The object representing a user-assigned managed identity has a unique value of isExplicit=True for the AlternativeNames property while a system-assigned managed identity has that value of isExplicit=False.
That’s it for this post folks. In the next post I’ll walk through the process of creating a managed identity for an Azure VM and will demonstrate with a bit of Python code how we can use the managed identity to access a secret stored in Azure Key Vault.
See you next post!