Cloud Experts Documentation

ARO Service Principal to Managed Identity: What Changes in Authentication and How to Move

This content is authored by Red Hat experts, but has not yet been tested on every supported configuration.

This article covers what changes in authentication, why managed identity matters, and how to plan your move.

TL;DR

What changed and what stays the same? Service principal (SP) remains fully supported; there is no deprecation timeline, and existing SP clusters continue to work. What changes with managed identity (MI) is how authentication works at both layers. At the cluster layer, a single shared credential with broad Contributor permissions is replaced by nine scoped managed identities (one per operator plus a cluster identity that manages federated credentials for the others), each with only the permissions it needs, with no secrets stored in the cluster. At the application layer, MI clusters enable workload identity, which lets your application pods authenticate to Azure services like Key Vault, Storage, and SQL Database without managing any credentials. This capability is not available on SP clusters. From a security perspective, MI is the recommended approach for all new ARO clusters.

How do I move? There is no in-place conversion: you deploy a new MI cluster alongside the existing one and migrate workloads using a blue-green approach. The migration effort depends on your workload complexity, not on the SP-to-MI change itself. Most applications need only Kubernetes manifest changes (replacing secret references with ServiceAccount annotations). This article covers what changes and why; for a hands-on walkthrough see the demo repositoryexternal link (opens in new tab) .

Why We Wrote This

When we started working with customers on ARO managed identity, we found ourselves answering the same questions over and over: “What actually changes?” “Do we have to move?” “What happens to our apps?” The official Microsoft documentation is thorough, but the answers are scattered across half a dozen articles.

We wrote this article to put everything in one place. If you are an architect evaluating whether to adopt managed identity, or a team lead planning a migration from an existing SP cluster, this should give you what you need to make the decision and understand the path forward.

What’s Different: SP vs MI in ARO

There are two layers of identity in ARO:

  1. Cluster components: how ARO’s own operators (networking, storage, ingress, DNS, etc.) authenticate to Azure APIs
  2. Application workloads: how your applications running on the cluster authenticate to Azure services

SP and MI handle both layers differently.

Cluster Components: How Operators Authenticate

Service Principal Cluster

A single service principal is shared by all eight cluster operators. The SP has broad Contributor access to the VNet and the entire managed resource group. The ARO platform injects the SP credentials into the cluster; operators read the same client ID and client secret at runtime.

sequenceDiagram participant Admin as Admin / DevOps participant EntraID as Microsoft Entra ID participant ARO as ARO Platform participant Operators as All 8 ARO Operators
(networking, storage,
ingress, DNS, etc.) participant Azure as Azure APIs
(VMs, LBs, Disks, DNS) rect rgb(255, 245, 238) Note over Admin,ARO: Setup (during cluster creation) Admin->>EntraID: 1. Create SP (or let az aro create do it) EntraID-->>Admin: Client ID + Client Secret
(default 1 year, max 2 years) Admin->>ARO: 2. Provide SP credentials to az aro create ARO->>ARO: 3. Inject SP credentials into cluster end rect rgb(238, 245, 255) Note over Operators,Azure: Runtime Operators->>Operators: 4. All operators read SAME credential Operators->>EntraID: 5. Authenticate with Client ID + Secret EntraID-->>Operators: 6. Access token Operators->>Azure: 7. API calls with BROAD Contributor permissions end Note over Operators: ⚠ One credential, shared by all operators
Contributor on VNet + entire managed RG

This model is simple and has been running ARO clusters reliably since the beginning. The key operational requirement is that the customer must rotate the client secret before it expires (default 1 year, maximum 2 years). Rotation is performed via az aro update, not by manually editing cluster secrets.

Managed Identity Cluster

Each of the eight cluster operators gets its own user-assigned managed identity with only the Azure permissions it needs. A ninth identity (the cluster identity) manages federated credentials for the other eight. No secrets are stored in the cluster.

sequenceDiagram participant Admin as Admin / DevOps participant MIs as 9 User-Assigned
Managed Identities participant EntraID as Microsoft Entra ID participant CCO as Cloud Credential
Operator (CCO) participant Operator as Individual ARO Operator
(e.g., ingress) participant Azure as Azure APIs
(scoped resource only) rect rgb(238, 255, 238) Note over Admin,EntraID: Setup (one-time) Admin->>MIs: 1. Create 9 managed identities Admin->>MIs: 2. Assign scoped built-in roles
(e.g., Ingress Operator role on subnets only) Admin->>EntraID: 3. Create federated credentials
(link each MI → operator ServiceAccount via OIDC issuer) end rect rgb(238, 245, 255) Note over CCO,Azure: Runtime CCO->>Operator: 4. Projected service account token
(short-lived K8s JWT, unique per operator, auto-rotated) Operator->>EntraID: 5. OIDC token exchange
(K8s JWT → Azure token) EntraID->>EntraID: 6. Validate JWT against cluster OIDC issuer EntraID-->>Operator: 7. Scoped Azure access token Operator->>Azure: 8. API calls with LEAST-PRIVILEGE permissions end Note over Operator: ✓ No secrets in cluster
Each operator: own identity, scoped role

If one operator’s identity is compromised, the blast radius is limited to that operator’s resources only. Other operators are unaffected.

Application Workloads: How Your Apps Authenticate

The choice between SP and MI also determines how your application pods can authenticate to Azure services like Key Vault, Storage, or SQL Database.

On an SP cluster, there is no OIDC issuer. Your applications must create their own service principals with secrets to access Azure services, which means managing credential rotation at the application layer as well.

On an MI cluster, the OIDC issuer is enabled. Your applications can use workload identity to authenticate without any secrets:

sequenceDiagram participant Admin as Admin / DevOps participant MI as App Managed Identity
(e.g., keyvault-reader-identity) participant EntraID as Microsoft Entra ID participant Webhook as Workload Identity
Webhook participant Pod as Your Application Pod participant SDK as Azure SDK
(DefaultAzureCredential) participant Azure as Azure Service
(Key Vault, Storage, SQL, etc.) rect rgb(238, 255, 238) Note over Admin,EntraID: Setup (one-time, per application) Admin->>MI: 1. Create user-assigned managed identity Admin->>MI: 2. Assign role scoped to specific resource
(e.g., Key Vault Secrets User on one vault) Admin->>EntraID: 3. Create federated credential
(link MI → K8s ServiceAccount via OIDC issuer) Note over Admin: 4. Annotate ServiceAccount:
azure.workload.identity/client-id
Label pod: azure.workload.identity/use: "true" end rect rgb(238, 245, 255) Note over Webhook,Azure: Runtime (every pod start) Webhook->>Pod: 5. Webhook injects into pod:
• AZURE_CLIENT_ID
• AZURE_TENANT_ID
• AZURE_FEDERATED_TOKEN_FILE
• AZURE_AUTHORITY_HOST
• Projected volume (short-lived K8s JWT) Pod->>SDK: 6. App calls DefaultAzureCredential() SDK->>SDK: 7. Reads K8s JWT from projected volume SDK->>EntraID: 8. OIDC token exchange
(K8s JWT → Azure access token) EntraID->>EntraID: 9. Validates JWT against cluster OIDC issuer EntraID-->>SDK: 10. Azure access token (~1 hour) SDK->>Azure: 11. API call with scoped token Azure-->>Pod: 12. Response end Note over Pod: ✓ No secrets in pod or cluster
Token scoped to one identity, one resource

This is the same pattern used by ROSA with IAM Roles for Service Accounts (IRSA) and OSD with Workload Identity on GCP. The Azure SDK’s DefaultAzureCredential handles the token exchange automatically; your application code does not need to know which authentication method is being used.

Workload identity is only available on MI clusters. If your applications need secretless access to Azure services, an MI cluster is a prerequisite.

Summary: What Changes at Each Layer

Layer Service Principal Cluster Managed Identity Cluster
Cluster operators 1 shared SP with Contributor role 9 scoped MIs with least-privilege roles
Application workloads Apps manage their own SP credentials Workload identity (secretless via OIDC)
Credentials in cluster Client secret (default 1-year expiry, max 2 years) None: short-lived tokens, auto-rotated
Blast radius Shared credential covers all operators Each operator isolated to its own scope
Credential management Customer rotates on schedule Azure handles automatically

Diagram sources: These authentication flows were compiled from Managed identities for Azure resourcesexternal link (opens in new tab) , Understand managed identities in AROexternal link (opens in new tab) , Deploy and configure an application using workload identity on AROexternal link (opens in new tab) , and Demystifying Service Principals & Managed Identitiesexternal link (opens in new tab) . The official docs describe each model in isolation; these diagrams place them side-by-side in the ARO context to highlight the operational differences.

Why Managed Identity

Is MI a Must?

No. Service principal is fully supported for both existing and new ARO clusters. There is no deprecation timeline. If you have an SP cluster running today, it will continue to work.

Why You Should Consider It Anyway

1. No credentials to manage. Service principal clusters work well, but they do require you to track and rotate the client secret before it expires. Managed identity removes this operational task entirely: Azure handles the credential lifecycle automatically with short-lived tokens that rotate without any manual intervention.

2. Least-privilege per operator. With a service principal, all operators share the same Contributor permissions, which is straightforward but broader than any single operator needs. Managed identity refines this by assigning each operator its own scoped Azure built-in role (the ingress operator can only manage ingress resources, the storage operator can only manage storage), reducing the potential impact if any single component is compromised.

3. Workload identity for applications. This is the capability that only MI clusters can provide. MI clusters include an OIDC issuer, which enables your application pods to authenticate to Azure services (Key Vault, Storage, SQL Database) using DefaultAzureCredential, with no secrets stored in the cluster or in your application configuration. On SP clusters, applications that access Azure services need their own service principals with secrets, which means managing credential rotation at the application layer as well.

4. Consistent with other OpenShift managed services. ROSA on AWS already uses IAM Roles for Service Accounts (IRSA) and OSD on GCP uses Workload Identity; both follow the same pattern of short-lived, OIDC-based credentials scoped per component. ARO’s managed identity model brings the same approach to Azure. Organizations running multiple OpenShift managed services will find a consistent security model across clouds.

5. Tooling support. The Azure Portal already automates MI setup: managed identities, role assignments, and federated credentials are created automatically when you deploy a new ARO cluster through the portal. The az aro CLI does not yet automate this, so CLI-based deployments currently require manual identity and role assignment setup. A simplified CLI experience is expected to be available soon.

MI Operational Considerations

Migrating from SP to MI

There Is No In-Place Migration

You cannot convert an existing SP cluster to MI. Managed identity can only be enabled on new clusters. The migration is a standard blue-green cluster migration with a few SP→MI-specific considerations. The migration effort depends on your workload complexity, not on the SP-to-MI change itself.

Migration Methodology

Phase 1: Prepare the new cluster

  1. Deploy a new MI-based ARO cluster alongside the existing SP cluster
  2. Configure cluster-level settings (IDP, monitoring, network policies, pull secret)
  3. Create Azure managed identities and federated credentials for each application that accesses Azure services

Phase 2: Adapt application configurations

The cluster infrastructure changes, but your application code may not need to. What changes depends on how your apps authenticate to Azure:

Scenario Code change? Config change?
App uses DefaultAzureCredential (Azure SDK) No: SDK auto-detects workload identity (ensure SDK meets minimum version ) Yes: replace K8s Secret with ServiceAccount annotation
App uses explicit ClientSecretCredential Yes: change to DefaultAzureCredential Yes: replace K8s Secret with ServiceAccount annotation
App authenticates via connection strings (e.g., Storage account key, SQL password) No: deploy as-is (these don’t use SP) No: optionally migrate to workload identity later for secretless access
App does not access Azure services No No: deploy as-is
Stateful app with PVC (Azure Disk) No Yes: backup data, recreate PVC on new cluster, restore
App using Azure Files (RWX) No Yes: create StorageClass manually on MI cluster first

For each app that accesses Azure services via the Azure SDK, the K8s manifest changes are:

  • Remove: Secret references (envFrom or env.valueFrom) that inject AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID
  • Add: ServiceAccount with annotation azure.workload.identity/client-id: <managed-identity-client-id>
  • Add: Pod label azure.workload.identity/use: "true"
  • Set: .spec.serviceAccountName in the pod/deployment spec to reference the annotated ServiceAccount

The workload identity webhook automatically injects the credentials into the pod at runtime.

Azure SDK Minimum Versions

If your app already uses DefaultAzureCredential, ensure the Azure Identity SDK version includes WorkloadIdentityCredential support:

Language Library Minimum version
.NET Azure.Identity 1.9.0
Go azidentity 1.3.0
Java azure-identity 1.9.0
Node.js @azure/identity 3.2.0
Python azure-identity 1.13.0

Older SDK versions will not auto-detect workload identity, even if the webhook injects the correct environment variables.

Phase 3: Deploy and validate

  1. Deploy workloads to the new MI cluster using your existing CI/CD pipelines (GitOps, Helm, or pipeline redeploy)
  2. Validate each application’s Azure service connectivity (Key Vault reads, storage writes, database queries)
  3. Run integration tests or smoke tests

Phase 4: Traffic cutover

  1. Shift traffic from the old cluster to the new cluster (DNS update, Azure Front Door, or load balancer reconfiguration)
  2. Monitor for errors during the transition period
  3. Keep the old SP cluster running as a rollback option until confident

Phase 5: Decommission

  1. Decommission the old SP cluster after a validation period
  2. Remove the old service principal and its app registration from Entra ID
  3. Clean up the old resource group

Hands-On Demo

The rh-mobb/example-aro-sp-to-miwiexternal link (opens in new tab) repository contains two Python Flask demo applications and a step-by-step walkthrough for migrating them from an SP cluster to an MI cluster with workload identity:

  • keyvault-reader — reads secrets from Azure Key Vault using ClientSecretCredential on the SP cluster. Demonstrates the most common migration case: a one-line code change to DefaultAzureCredential plus replacing the K8s Secret with a ServiceAccount annotation.
  • blob-writer — writes to Azure Blob Storage using DefaultAzureCredential on both clusters. Demonstrates that apps already using DefaultAzureCredential need no code change at all — only the K8s manifest changes.

The README walks through environment setup, creating managed identities and federated credentials, building and deploying both apps on the MI cluster, and validating that workload identity is working with no secrets in the pods.

References

Back to top

Interested in contributing to these docs?

Collaboration drives progress. Help improve our documentation The Red Hat Way.

Red Hat logo LinkedIn YouTube Facebook Twitter

Products

Tools

Try, buy & sell

Communicate

About Red Hat

We’re the world’s leading provider of enterprise open source solutions—including Linux, cloud, container, and Kubernetes. We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Subscribe to our newsletter, Red Hat Shares

Sign up now
© 2026 Red Hat