Managed Identities for Azure Resources
Complete the full lesson to earn 25 points
Work through each section, then tap “Mark as Complete” on the last one.
Managed Identities for Azure Resources: A Comprehensive Guide
Introduction: Why Identity Management Matters in the Cloud
In the early days of cloud computing, developers frequently faced a significant security hurdle: how to grant an application permission to access other cloud resources without hardcoding credentials. You have likely seen codebases where connection strings, service principal keys, or database passwords were stored in configuration files or environment variables. This practice is a major security risk. If a configuration file is accidentally pushed to a version control system like GitHub, an attacker can gain unauthorized access to your infrastructure, potentially leading to data breaches or financial loss.
Managed Identities for Azure Resources provide a clean, secure solution to this problem. Instead of managing credentials yourself, Azure handles them for you. When you enable a Managed Identity, Azure creates an identity in Microsoft Entra ID (formerly Azure Active Directory) for your resource—such as a virtual machine, function app, or container instance. Your code can then use this identity to authenticate to any service that supports Microsoft Entra authentication, such as Azure Key Vault, Azure SQL Database, or Azure Storage, without ever handling a password.
Understanding Managed Identities is foundational for any Azure professional. It is the industry-standard way to implement the principle of least privilege in the cloud. By moving away from static credentials, you reduce the surface area for attacks and simplify the operational burden of rotating secrets. This lesson will walk you through the mechanics of Managed Identities, how to implement them, and how to follow best practices to keep your infrastructure secure.
Understanding the Core Concepts
To work effectively with Managed Identities, you must first understand the two primary types: System-Assigned and User-Assigned. While both serve the goal of identity management, they operate with different lifecycles and use cases.
System-Assigned Managed Identities
A System-Assigned Managed Identity is tied directly to the lifecycle of the Azure resource. When you enable it on a specific resource—for example, a Virtual Machine—Azure creates an identity that is locked to that resource. If you delete the virtual machine, Azure automatically deletes the identity. This is the simplest way to get started because you do not have to manage the creation or assignment of the identity object separately.
User-Assigned Managed Identities
A User-Assigned Managed Identity is created as a standalone Azure resource. Because it is a separate object, it can be assigned to multiple resources simultaneously. For example, if you have a fleet of twenty virtual machines that all need access to the same storage account, you can create one User-Assigned Identity and attach it to all twenty machines. This is highly beneficial for complex environments where you want to centralize identity management and reuse permissions across different services.
Callout: System vs. User-Assigned Identities Think of a System-Assigned identity like a badge issued specifically for a single employee that expires when they leave the company. It is easy to manage but limited in scope. Think of a User-Assigned identity like a departmental access card that can be handed to any employee who needs access to that department’s resources. It requires more setup but offers greater flexibility for scaling and shared access.
How Authentication Actually Works
When your application code runs on a resource with a Managed Identity, it requests an access token from a local endpoint provided by the Azure platform. This endpoint is accessible only from within the resource. Your code sends a request to this internal address, and the Azure platform returns a Microsoft Entra ID token. Your application then presents this token to the target resource (like an Azure Key Vault) to prove its identity. The entire exchange happens via HTTPS, and no actual credentials are ever exposed in your application logs or configuration files.
Implementing Managed Identities: Step-by-Step
Implementing Managed Identities involves two main phases: enabling the identity on the resource and assigning the necessary permissions (RBAC roles) to that identity.
Enabling a System-Assigned Identity
Let’s look at how to enable a System-Assigned Identity on an Azure Function App.
- Navigate to your Function App in the Azure portal.
- Under the "Settings" section in the left-hand menu, click on "Identity."
- In the "System assigned" tab, toggle the "Status" to "On."
- Click "Save."
Once you click save, Azure registers the application with Microsoft Entra ID. You will see an "Object (principal) ID" appear. This ID is the unique identifier you will use when assigning roles in the next step.
Assigning Permissions via RBAC
An identity is useless without permissions. You must grant the identity access to the specific resources it needs. Using the Azure portal:
- Navigate to the resource you want the Function App to access (e.g., an Azure Storage Account).
- Click on "Access Control (IAM)."
- Select "Add" and then "Add role assignment."
- Choose the appropriate role (e.g., "Storage Blob Data Contributor").
- On the "Members" tab, select "Managed Identity."
- Click "+ Select members," choose the subscription, and then select the specific Function App you configured in the previous step.
- Click "Review + assign."
Tip: Always use the principle of least privilege. If your application only needs to read data, do not assign the "Contributor" role. Look for "Reader" or specific data-plane roles like "Storage Blob Data Reader."
Using Managed Identities in Code
Now that the infrastructure is configured, your code needs to request the token. You do not need to build this from scratch; the Azure Identity library handles the heavy lifting for you.
Example: Accessing Azure Key Vault with Python
The following Python example demonstrates how to authenticate to Key Vault using the DefaultAzureCredential class. This class is designed to automatically try several authentication methods, with Managed Identity being one of the preferred ones.
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
# The vault URL is the only configuration needed
vault_url = "https://my-secure-vault.vault.azure.net/"
# DefaultAzureCredential will automatically detect the Managed Identity
# when running on an Azure resource.
credential = DefaultAzureCredential()
# Initialize the client
client = SecretClient(vault_url=vault_url, credential=credential)
# Retrieve a secret
secret = client.get_secret("my-database-password")
print(f"The secret value is: {secret.value}")
Why this code is effective:
- Zero Credentials: Notice that there are no usernames, passwords, or client secrets in the code.
- Portability: If you run this code on your local machine,
DefaultAzureCredentialcan use your logged-in Azure CLI credentials. When you deploy it to Azure, it automatically switches to the Managed Identity. - Security: The token acquisition and renewal process are handled automatically by the Azure SDK, keeping your application code clean and secure.
Comparison of Identity Options
To help you choose the right approach for your architecture, refer to the table below.
| Feature | Hardcoded Credentials | Service Principals | Managed Identities |
|---|---|---|---|
| Security | Very Low | Moderate | Very High |
| Credential Rotation | Manual | Manual/Scripted | Automatic |
| Ease of Use | Simple | Complex | Very Simple |
| Best For | Never use | Legacy/Non-Azure | Modern Azure apps |
Best Practices and Industry Standards
Adopting Managed Identities is a significant step toward a secure architecture, but you must implement them correctly to gain the full benefit.
1. Prioritize User-Assigned Identities for Scalability
While System-Assigned identities are easy to set up, they become difficult to manage in large, multi-resource architectures. If you have a microservices application where multiple components need the same set of permissions, use a User-Assigned identity. This allows you to update the permissions for all components at once by updating the single User-Assigned identity.
2. Audit Identity Usage
Periodically review which resources have Managed Identities and what permissions they hold. Use Azure Policy to enforce that resources are configured according to your security standards. For example, you can create a policy that denies the creation of any virtual machine that does not have a Managed Identity enabled.
3. Avoid "Over-Permissioning"
It is tempting to grant "Owner" or "Contributor" access to a Managed Identity to avoid troubleshooting permission errors. This is dangerous. If that identity is compromised, the attacker has full control over the resource. Always use specific, granular roles. If you find that a built-in role is too broad, create a custom RBAC role with only the specific actions required.
4. Monitor with Microsoft Entra Sign-in Logs
You can track the activity of your Managed Identities by checking the sign-in logs in Microsoft Entra ID. Filter by the identity's name to see when it was used and what resources it accessed. This is invaluable for troubleshooting and for forensic analysis if you suspect an anomaly.
Warning: Never use Managed Identities to grant human access to resources. Managed Identities are strictly for applications and services. If you need to access a resource as a person, use your individual Entra ID account with Multi-Factor Authentication (MFA).
Common Pitfalls and How to Avoid Them
Even with a strong understanding, developers often run into specific issues when working with Managed Identities. Being aware of these will save you hours of debugging.
The "Permission Propagation" Delay
After you assign a role to a Managed Identity, it may take a few minutes for the change to propagate across Azure’s global control plane. If your code immediately tries to access the resource and receives a 403 Forbidden error, do not panic. Wait a few minutes and try again. If the issue persists, check the RBAC assignment again to ensure you selected the correct object ID.
The Local Development Trap
Many developers struggle because their code works in Azure but fails on their local machine. This is because DefaultAzureCredential looks for a Managed Identity, which does not exist on your laptop.
- The Fix: Install the Azure CLI on your local machine and run
az login.DefaultAzureCredentialwill detect your local session and use your personal credentials to perform the same actions, allowing you to test your logic before deployment.
Misunderstanding the Scope
When assigning roles, ensure you are assigning them at the correct scope. If you assign a role at the Resource Group level, that identity will have access to every resource within that group. If you only need access to a single storage account, assign the role directly on the storage account itself. Narrowing the scope reduces the blast radius if an identity is ever compromised.
Ignoring Token Expiry
While the Azure SDK handles token renewal, if you are writing custom code to fetch tokens (using the REST API directly), you must implement your own logic to handle token expiration. If you do not refresh the token before it expires, your application will lose access to the downstream service. Always prefer using the official Azure SDK libraries over manual REST calls to avoid this complexity.
Deep Dive: Managing User-Assigned Identities at Scale
In enterprise environments, managing identity lifecycles is as important as the identity itself. When you use User-Assigned identities, you are effectively creating an asset that needs to be tracked.
The Lifecycle of a User-Assigned Identity
- Creation: Create the identity via Terraform, Bicep, or the Azure CLI.
- Assignment: Attach the identity to your compute resources (VMs, AKS, Functions).
- Authorization: Assign the identity to the necessary target resources (Key Vaults, Databases).
- Monitoring: Use Azure Monitor to track the usage of the identity.
- Cleanup: When the application is decommissioned, ensure that the identity is also deleted to avoid "dangling" identities.
Infrastructure as Code (IaC) Integration
You should never manually create identities in a production environment. Use tools like Bicep or Terraform to define your identities. Here is a brief example of how to define a User-Assigned identity using Bicep:
resource myIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: 'my-app-identity'
location: resourceGroup().location
}
output identityPrincipalId string = myIdentity.properties.principalId
By defining the identity in code, you ensure that the identity is recreated consistently across environments (Dev, Test, Prod) and that it is destroyed automatically when the infrastructure stack is torn down.
Frequently Asked Questions (FAQ)
Q: Can I use Managed Identities for on-premises servers? A: No, Managed Identities are specifically for resources hosted within the Azure platform. For on-premises servers, you should use service principals or workload identity federation to authenticate with Azure.
Q: What happens if I move a resource to a different subscription? A: If you move a resource with a System-Assigned identity, the identity will be recreated in the new subscription, and you will need to re-assign all your RBAC roles. User-Assigned identities are more portable, but you still need to ensure the identity exists in the target subscription or is accessible.
Q: Is there a limit to how many Managed Identities I can have? A: Yes, Azure has limits on the number of identities per subscription. However, these limits are quite high and rarely pose an issue for most organizations. You can check the current limits in the Azure portal under "Subscription" -> "Usage + quotas."
Q: Can I share a Managed Identity across different tenants? A: Generally, Managed Identities are scoped to a single Microsoft Entra tenant. If you have a multi-tenant application, you will need to handle cross-tenant authentication using standard OAuth 2.0 flows, not Managed Identities.
Key Takeaways for Secure Azure Solutions
To wrap up this lesson, here are the most critical points to remember when implementing Managed Identities in your projects:
- Eliminate Secrets: The primary goal of Managed Identities is to eliminate the need for hardcoded credentials. If your code contains a password or a connection string, you are doing it wrong.
- Default to Managed Identities: Whenever you are building an application that runs on Azure, assume you will use a Managed Identity. It is the most secure and easiest method to manage.
- Choose the Right Type: Use System-Assigned identities for simple, one-off resources. Use User-Assigned identities for complex, scalable architectures where multiple resources share the same permission set.
- Enforce Least Privilege: Never assign more access than a resource needs. Use granular RBAC roles and limit the scope of assignments to the smallest possible boundary (e.g., the specific storage account instead of the whole subscription).
- Use the Azure SDK: Always use the official Azure SDKs (like
azure-identityin Python, JS, or C#). They are built to handle token acquisition, caching, and renewal, which prevents common bugs and security issues. - Automate with IaC: Treat Managed Identities like any other piece of infrastructure. Define them in your Bicep or Terraform templates to ensure consistency and easier lifecycle management.
- Audit and Monitor: Regularly check your Entra ID sign-in logs and use Azure Policy to ensure that your resources are using Managed Identities and that those identities are not over-privileged.
By following these principles, you will significantly improve the security posture of your Azure solutions. You will reduce the risk of credential leakage, simplify your operational overhead, and ensure that your applications are following modern, industry-standard practices for identity and access management. Keep practicing these patterns in your development lifecycle, and you will find that security becomes a natural, rather than an additional, part of your workflow.
Enjoying the courses?
Everything stays free. Pro shows fewer ads, doubles your daily points limit so you progress twice as fast, and lets you read each lesson on one page.
- ✓ Fewer advertisements
- ✓ 2× daily points limit
- ✓ Distraction-free lessons