Managed Identities: The Architect's Default Choice

You've used managed identities in AZ-104 labs. As an architect, the question shifts from "how do I enable one?" to "which type, for which topology, and what are the trade-offs at scale?"

🔑 Key Concept: No Secrets to Manage

Managed identities eliminate credential management entirely. Azure handles token issuance, rotation, and revocation through the Instance Metadata Service (IMDS). No secrets in Key Vault, no expiry alerts, no rotation runbooks.

System-Assigned Managed Identity

  • ✅ 1:1 tied to a single resource's lifecycle
  • ✅ Auto-created and auto-deleted with the resource
  • ✅ Easy to audit — identity maps directly to one resource
  • ✅ No orphaned identities possible
  • ❌ Cannot be shared across resources
  • ❌ Role assignments must be pre-created (chicken-and-egg with IaC)
  • ❌ Harder to pre-authorize before resource exists

User-Assigned Managed Identity

  • ✅ Independent lifecycle — create first, attach to many resources
  • ✅ Shared across multiple resources (e.g., a pool of VMs)
  • ✅ Pre-authorize in IaC before compute exists
  • ✅ Survives resource recreation (redeployments keep same identity)
  • ❌ Must be explicitly managed and cleaned up
  • ❌ Slightly harder to trace "which resource used this token?"
  • ❌ Possible orphaned identities if not governed
When to choose which — decision framework
  • Use system-assigned when: single-purpose resource, simple RBAC, you want automatic cleanup, audit trail clarity is paramount
  • Use user-assigned when: multiple resources need the same permissions (VMSS, container instances, blue-green deployments), you deploy with IaC and need to pre-stage role assignments, or the resource is frequently recreated
  • Use both together when: a resource needs a shared identity for common access (user-assigned) PLUS a unique identity for resource-specific access (system-assigned)

Service Principal Lifecycle at Scale

Service principals are still necessary when managed identities aren't an option — external CI/CD systems, third-party integrations, or multi-tenant app registrations. The architect's job: minimize their use and govern the ones that remain.

🔑 Key Concept: App Registration ≠ Service Principal

An App Registration is the global identity definition (lives in the home tenant). A Service Principal is the local instance of that app in a specific tenant. One app registration can have service principals in many tenants — this is how multi-tenant apps work.

⚠️ Secret Sprawl is an Architecture Failure

Every service principal with a client secret is a ticking clock. Secrets expire (max 2 years, recommended: much shorter). At scale, organizations accumulate hundreds of service principals with secrets that expire silently, breaking production. Architect for zero secrets wherever possible: managed identities first, workload identity federation second, certificates third, secrets as last resort.

Governing service principals at enterprise scale
  • Ownership: Every app registration must have at least 2 owners from the responsible team — enforce via Entra ID Access Reviews
  • Credential expiry: Set org-wide policy for max credential lifetime (e.g., 90 days). Monitor with Microsoft Graph applicationSignInDetailedSummary
  • Least privilege: Never grant tenant-wide admin consent to multi-tenant apps without security review
  • Naming convention: sp-{team}-{purpose}-{env} (e.g., sp-platform-ghactions-prod)
  • Regular review: Automate unused SP detection — if no sign-in activity in 90 days, flag for decommission

Workload Identity Federation for CI/CD

This is the modern replacement for storing Azure secrets in GitHub/GitLab/Jenkins. Instead of a client secret, your CI/CD platform presents its own token, and Azure trusts it directly via OIDC federation.

🔑 Key Concept: Trust the Platform's Token

Workload identity federation creates a trust relationship between Entra ID and an external identity provider (GitHub Actions, GitLab CI, Terraform Cloud, etc.). The external platform issues a short-lived OIDC token; Entra ID validates it and issues an Azure access token. No secrets cross system boundaries.

How It Works (GitHub Actions Example)

  1. Create an App Registration in Entra ID
  2. Add a federated credential specifying: GitHub org, repo, branch/environment
  3. Assign RBAC roles to the app's service principal
  4. In the GitHub workflow, use azure/login@v1 with client-id, tenant-id, subscription-id — no secret needed
Federation subject claims — scoping access precisely

The federated credential's subject field controls exactly which workflows can authenticate:

  • repo:org/repo:ref:refs/heads/main — only the main branch
  • repo:org/repo:environment:production — only the "production" GitHub Environment
  • repo:org/repo:pull_request — any PR (use for plan-only, never for apply)

Architect tip: Create separate federated credentials per environment. The "dev" credential should have narrow RBAC on dev subscriptions; "prod" should require the GitHub production environment (which enforces approvals).

📝 AZ-305 Exam Tip

When a scenario describes a CI/CD pipeline needing Azure access and mentions "minimize credential management" or "eliminate secrets" — the answer is workload identity federation. If the scenario says "on-premises Jenkins with no internet-facing IdP," federation isn't possible — fall back to certificate-based service principal with short expiry stored in Key Vault.

Cross-Tenant Identity Patterns

As an architect, you'll face scenarios where identities must work across organizational boundaries. Azure provides distinct mechanisms for distinct problems.

B2B Collaboration (Entra External ID)

Use case: Invite external users (partners, vendors, contractors) into YOUR tenant as guest users. They authenticate with their home tenant but get a shadow identity in yours.

Architect consideration: Guest users count toward directory limits. Use Access Packages (Entitlement Management) for lifecycle governance — auto-expire access after project ends.

B2C (Azure AD B2C / External ID for customers)

Use case: Customer-facing apps where end users sign up with email/social/local accounts. Completely separate directory from your corporate tenant.

Architect consideration: B2C is a separate tenant with its own policy engine (user flows / custom policies). It does NOT share the corporate Entra ID directory. Plan for separate governance.

Multi-Tenant App Registrations

Use case: Your SaaS app needs to access resources in customer tenants. Register your app as multi-tenant; customers consent and a service principal is created in their tenant.

Architect consideration: Customers control what permissions they grant via admin consent. Design for least-privilege scopes. Use application permissions (not delegated) for background/daemon access.

Cross-Tenant Access Settings

Use case: Fine-grained control over which external tenants can collaborate with yours. Define inbound (who can access your resources) and outbound (what your users can access elsewhere) policies per partner tenant.

Architect consideration: Default is "allow all B2B." For regulated industries, set default to "block all" and explicitly allow trusted partner tenant IDs.

Identity Architecture for Multi-Subscription Environments

🔑 Key Concept: One Tenant, Many Subscriptions

All subscriptions trust a single Entra ID tenant. Identity is the unifying layer across your entire Azure estate. RBAC role assignments can be scoped at management group level to span all subscriptions.

Design Patterns

  • Centralized identity team: Owns app registrations, manages Conditional Access, reviews service principal credentials. Platform team, not app teams.
  • User-assigned managed identities per workload: Create in a shared identity resource group; attach across subscriptions. Enables consistent permissions across dev/staging/prod.
  • Privileged Identity Management (PIM): No standing access to production subscriptions. JIT elevation with approval workflows and time-bounded activation.
  • Emergency access accounts: Two cloud-only Global Admin accounts with long passwords, no MFA (phishing-resistant hardware token excepted), stored in a physical safe. Monitored by alerts.

⚠️ Common Mistake: Over-Scoped Service Principals

A service principal with Contributor on a management group can modify every resource in every subscription beneath it. Scope permissions to the narrowest resource group possible. If a pipeline deploys to one resource group, grant Contributor on that resource group only — never the subscription.

Real-World Scenario

🏢 Case Study: DataLens (SaaS Analytics Vendor)

Situation: DataLens sells an analytics platform that needs to read data from customers' Azure Storage accounts and Azure SQL databases. Each customer has their own Azure tenant. DataLens must access customer resources without customers sharing secrets or storage keys.

Architecture Decision:

  1. Multi-tenant app registration: DataLens registers their app as multi-tenant in their home tenant with minimal permissions declared (e.g., Storage Blob Data Reader).
  2. Customer admin consent: Each customer's Azure admin reviews permissions and grants admin consent — this creates a service principal in the customer's tenant.
  3. Customer assigns RBAC: The customer grants the DataLens service principal Storage Blob Data Reader on specific storage accounts (not the whole subscription).
  4. Token acquisition: DataLens backend authenticates as the multi-tenant app, specifying the customer's tenant ID, and receives a token scoped to that customer's resources.
  5. No secrets in customer tenants: The credential (certificate or federated) lives only in DataLens's home tenant. Customers never see or manage it.

Why This Works:

  • Customer controls access: They can revoke consent or remove role assignments at any time
  • Least privilege: Read-only on specific storage accounts, not broad subscription access
  • No shared secrets: No storage keys, no SAS tokens, no customer-managed credentials
  • Audit trail: Every access appears in the customer's Entra ID sign-in logs under the DataLens service principal

Alternative Considered (and rejected):

Customer creates a service principal for DataLens with a client secret. Rejected because: the customer must manage secret rotation, there's no standard way to deliver secrets securely, and secret expiry breaks the integration silently.

Lesson Summary

  • Default to managed identities — system-assigned for single-resource simplicity, user-assigned for shared access and IaC-friendly pre-staging
  • Service principals still needed for external systems and multi-tenant apps — govern with ownership, short credential lifetimes, and regular reviews
  • Workload identity federation eliminates secrets for CI/CD — trust the platform's OIDC token instead
  • Cross-tenant: B2B for partner collaboration, B2C for customers, multi-tenant apps for SaaS accessing customer resources
  • Multi-subscription identity: centralize governance, scope narrowly, use PIM for production access
  • Architect mindset: every secret is a liability; every standing permission is an attack surface

Knowledge Check