First, a quick clarification on terminology since it comes up a lot: “Workload Identity” is an umbrella term for any non-human identity in Entra ID. Under that umbrella you have a few distinct things, App Registrations/Service Principals, Managed Identities, and Workload Identity Federation. Managed Identity is a specific type of workload identity, not a synonym for it. That distinction matters when we’re talking about what controls and policies apply.
For app-to-app authentication (no user involved), moving toward the right workload identity pattern is absolutely the right direction. App registrations configured as Single Page Apps or Web Apps are designed for user-facing authentication flows (OAuth authorization code, OIDC), so using them for service-to-service communication is working against the grain. A service principal with tightly scoped API permissions is cleaner, more auditable, and purpose-built for that scenario.
Here’s where the different workload identity types shine and where we get better security controls:
Managed Identities: This may be what you are looking to implement or your requests. You can learn more about Managed Identities HERE. For anything running inside Azure (VMs, App Service, Functions, AKS), Managed Identities should be the default. No app registration required, no credentials to manage or rotate, and they integrate directly with Azure RBAC. The identity lifecycle is tied to the resource itself. This is the lowest-friction, highest-security option when it’s available.
Service Principals (App Registrations without the SPA/Web App config): For workloads running outside Azure, or where you need cross-tenant access, a service principal is the right tool. This is where credential hygiene matters most; HOWEVER….. you should be standardizing on certificates over client secrets, or better yet Workload Identity Federation for workloads in GitHub Actions, Azure DevOps, or Kubernetes.
Conditional Access for Workload Identities: Consider this, Entra ID supports Conditional Access policies specifically targeting service principals. We can restrict authentication to known IP ranges or trusted locations, block sign-ins outside expected network boundaries, and enforce compliant credential types.
On minimizing Single Page App registrations: a big driver of the volume is likely teams treating each app or environment (dev/staging/prod) as a separate registration, or using SPAs for flows that don’t involve a user at all. Some practical ways to reduce this:
- Add an intake question: “Is a user signing in, or is this service-to-service?”
- This alone will redirect a lot of requests!
- Consolidate environments under one registration using multiple redirect URIs
- Establish Managed Identity as the default for Azure-hosted workloads before a registration request is even considered
One of the most impactful things you could do is to have a comprehensive discovery intake form that teams must complete before a registration is created. The form should capture key routing questions like whether a user is actually signing in, where the workload is hosted, what APIs or resources it needs to access, and whether the workload has an existing identity provider.
Happy to put together a decision framework or lightweight intake policy if that would be useful.