Managed Identity vs Service Principal: cuál usar en Azure
En pocas palabras: Usá managed identity si tu código corre en Azure: Microsoft la crea, guarda y rota sin que veas la credencial. Elegí service principal solo para GitHub Actions, on-premises u otra nube, y preferí certificado o federación antes que un client secret, que caduca a los 24 meses.
Una managed identity es un service principal especial que Azure crea, guarda y rota por vos, sin que puedas verle la credencial. En noviembre de 2026, la elección entre managed identity vs service principal depende de un solo factor: quién administra ese secreto. Si tu código corre en Azure, no hay mucho que pensar.
Una managed identity es una identidad de Microsoft Entra ID que Azure asigna a un recurso (VM, App Service, Logic App) y cuya credencial nunca ves ni gestionás. Un service principal tradicional es la identidad que crea una aplicación para autenticarse en Azure, pero ahí el secreto, certificado o credencial lo generás, guardás y rotás vos mismo según la documentación de Microsoft Learn.
En este artículo:
- En 30 segundos
- ¿Qué es una managed identity y en qué se diferencia de un service principal?
- Identidad asignada por el sistema vs asignada por el usuario: ¿cuál conviene?
- ¿Cuándo sigue siendo necesario un service principal tradicional?
- ¿Cómo configurar una managed identity para una App Service?
- ¿Cómo configurar un service principal sin secreto para GitHub Actions?
- ¿Qué errores comunes aparecen después de implementar managed identity o service principal?
- Managed identity vs service principal: tabla comparativa
- Errores comunes al elegir entre managed identity y service principal
- Preguntas Frecuentes
- Conclusión
- Fuentes
En 30 segundos
- Toda managed identity es, por debajo, un service principal especial en Entra ID: la diferencia es quién maneja la credencial.
- Hay dos tipos: system-assigned (atada al recurso) y user-assigned (independiente, se puede compartir entre varios recursos).
- Los client secrets de un service principal duran como máximo 24 meses, aunque Microsoft recomienda rotarlos antes de los 12.
- Azure cachea los tokens de managed identity unas 24 horas, así que un cambio de rol puede tardar en reflejarse.
- Para GitHub Actions, on-premises u otra nube no hay managed identity disponible: ahí entra el service principal con federación OIDC.
¿Qué es una managed identity y en qué se diferencia de un service principal?
La diferencia real no está en el nombre, está en quién toca la credencial. Según Microsoft Learn, cuando habilitás una managed identity, Azure crea automáticamente “un service principal de un tipo especial” en Entra ID para esa identidad. Ese service principal está ahí, existe, pero vos nunca ves ni manejás su secreto.
Con un service principal tradicional (lo que en la jerga se llama app registration) la historia es otra: vos generás un client secret o un certificado, lo guardás en algún lado (idealmente un key vault, no un archivo .env en tu laptop) y tenés que acordarte de rotarlo antes de que expire. Ese trabajo manual es exactamente lo que la managed identity elimina.
Ojo: esto no es una guerra entre dos tecnologías rivales. Es la misma base de identidad de Entra ID con dos modelos de gestión de credenciales distintos. Managed identities no tienen costo extra, dice la misma página de Microsoft, así que la pregunta de “cuál me conviene” rara vez es de presupuesto. Es de dónde corre tu código.
Identidad asignada por el sistema vs asignada por el usuario: ¿cuál conviene?
Conviene user-assigned cuando varios recursos comparten acceso o cuando los recursos se crean y destruyen seguido; conviene system-assigned cuando el permiso tiene que desaparecer junto con el recurso. Son las dos variantes de managed identity y elegir mal trae dolores de cabeza después del primer despliegue. Esto se conecta con lo que analizamos en el artículo sobre cómo desplegar Microsoft Fabric con un service principal.
- System-assigned: vive pegada a un único recurso de Azure (una VM, un App Service). Si borrás el recurso, Azure borra la identidad con él. No se puede compartir.
- User-assigned: es un recurso independiente que vos creás, asignás a uno o más recursos, y borrás cuando quieras. Sobrevive aunque el recurso que la usa desaparezca.
El ejemplo que da Microsoft en su guía de mejores prácticas es contundente: cuatro VMs con identidades user-assigned compartidas necesitan solamente dos asignaciones de rol. Las mismas cuatro VMs con system-assigned necesitan ocho. Cuando tenés decenas de VMs creándose y destruyéndose, además, podés chocar contra el límite de creación de objetos en Entra ID y recibir un HTTP 429 (demasiadas solicitudes). Eso pasa porque cada identidad system-assigned nueva implica crear un objeto de service principal, y ese proceso tiene un rate limit.
Hay un matiz que se pasa por alto seguido: con user-assigned podés otorgar permisos antes de que el recurso exista. Con system-assigned, no, porque la identidad aparece junto con el recurso. Si tu pipeline de infraestructura necesita preautorizar accesos, user-assigned es la única opción viable.
¿Cuándo sigue siendo necesario un service principal tradicional?
Necesitás un service principal cuando tu workload corre en un lugar donde no hay managed identity disponible: runners de GitHub Actions, servidores on-premises u otra nube. Ahí no hay forma de esquivarlo, la managed identity es exclusiva de recursos de cómputo de Azure.
Eso sí: tener que usar un service principal no significa resignarse a un secreto guardado en algún lado. Microsoft dice directamente que los client secrets son menos seguros que un certificado o una credencial federada, y que no deberían usarse en producción. La salida es workload identity federation: tu app registration (o una user-assigned identity) confía en los tokens que emite un proveedor externo, como GitHub, y los canjea por un token de Entra sin que exista ningún secreto almacenado. Sobre eso hablamos en el artículo sobre conectarte por SSH a una VM de Azure.
Hay dos límites técnicos que conviene tener presentes acá. Las identidades system-assigned no pueden tener credenciales federadas (solo user-assigned o app registrations), y cualquier app o user-assigned identity puede tener como máximo 20 credenciales federadas simultáneas.
¿Cómo configurar una managed identity para una App Service?
Se configura creando primero la identidad user-assigned con az identity create y después asignándola al recurso con az webapp identity assign, sin tocar el rol por defecto que trae ese comando.
az identity create --name app-uami --resource-group rg-app --location centralus
az webapp identity assign -g rg-app -n my-web-app --identities app-uamiAcá viene lo que casi nadie lee en la letra chica: dejá --scope afuera de az webapp identity assign. ¿Por qué? Porque el rol por defecto que asigna ese comando es Contributor, que es un permiso bastante amplio para lo que probablemente necesitás. Lo correcto es asignar el rol acotado en un paso aparte:
PRINCIPAL_ID=$(az identity show --name app-uami --resource-group rg-app --query principalId --output tsv)
az role assignment create \
--assignee-object-id "$PRINCIPAL_ID" \
--assignee-principal-type ServicePrincipal \
--role "Storage Blob Data Reader" \
--scope /subscriptions//resourceGroups/rg-app/providers/Microsoft.Storage/storageAccounts/ Pasar --assignee-object-id salta la búsqueda en Microsoft Graph, y combinarlo con --assignee-principal-type ServicePrincipal evita errores de latencia de propagación, según la referencia de Azure CLI. Más contexto en el artículo sobre qué certificación de Azure conviene según tu rol.
¿Cómo configurar un service principal sin secreto para GitHub Actions?
Se configura con az ad sp create-for-rbac --create-password false, que crea el service principal sin generar ningún client secret, y después se agrega una credencial federada que confía en los tokens OIDC de GitHub.
az ad sp create-for-rbac --name gh-deploy --create-password false \
--role Reader --scopes /subscriptions//resourceGroups/rg-app El paso siguiente es agregar la federated credential en la app registration, bajo “Certificates & secrets”. El issuer tiene que ser https://token.actions.githubusercontent.com y el audience api://AzureADTokenExchange. En el workflow de GitHub, necesitás el permiso id-token: write y usar la acción oficial de login:
permissions:
id-token: write
contents: read
steps:
- uses: azure/login@v2
with:
client-id: ${ secrets.AZURE_CLIENT_ID }
tenant-id: ${ secrets.AZURE_TENANT_ID }
subscription-id: ${ secrets.AZURE_SUBSCRIPTION_ID }Ningún secreto queda almacenado en GitHub ni en Azure. El token que emite GitHub vive solo durante ese job y expira automáticamente, según explica la documentación de GitHub sobre OIDC.
¿Qué errores comunes aparecen después de implementar managed identity o service principal?
El error más frecuente es asumir que un cambio de rol se aplica al instante, cuando Azure cachea los tokens de managed identity por recurso durante unas 24 horas y no hay forma de forzar el refresco. Si tu app sigue tirando 403 después de agregar un permiso, el token viejo cacheado es el sospechoso número uno.
- Role assignments huérfanos: borrar una identidad no borra sus asignaciones de rol. Quedan como “Identity not found” y cuentan contra el límite de 5.000 asignaciones por suscripción. El comando de limpieza de PowerShell que da Microsoft filtra por
ObjectType -eq "Unknown", pero corré primero elGet-AzRoleAssignmentsolo, leé la lista, y después borrá. - El subject de la credencial federada falla en silencio: Entra acepta un
subjectmal escrito al crear la credencial. El error recién aparece en el intercambio de tokens. El matching es sensible a mayúsculas y no admite wildcards. - GitHub cambió el formato del sub claim: para repositorios creados después del 15 de julio de 2026, la referencia OIDC de GitHub indica que el
subpor defecto incluye los IDs de owner y repositorio, no solo el nombre. Una credencial federada copiada de un workflow viejo no va a matchear con un repo nuevo. - Colisión 409 en ARM templates: crear varias credenciales federadas en paralelo bajo la misma identidad puede devolver un conflicto. Hay que crearlas de una en una.
Un detalle que se olvida seguido: cualquiera que pueda ejecutar código en el recurso puede usar su identidad. El ejemplo de Microsoft es claro: un usuario sin acceso directo a storage puede leer esa cuenta de storage a través de la managed identity de la Logic App donde corre su código. El permiso de ejecutar código vale tanto como el permiso de acceso en sí. Lo explicamos a fondo en cómo se integran Microsoft y GitHub en este ecosistema.
Managed identity vs service principal: tabla comparativa
| Aspecto | Managed identity | Service principal (app registration) |
|---|---|---|
| Credencial | Ninguna que puedas ver o filtrar | Client secret, certificado o credencial federada |
| Dónde corre el código | Cómputo de Azure compatible | Cualquier lugar |
| Riesgo de expiración | Ninguno | Los secretos duran hasta 24 meses |
| Ciclo de vida | System-assigned: atada al recurso. User-assigned: independiente | Hasta que borrás la app |
| Compartir entre recursos | User-assigned puede atarse a varios | Cualquiera que tenga la credencial |
| Mejor uso | Workloads corriendo en Azure | CI/CD, on-premises, otras nubes |

Errores comunes al elegir entre managed identity y service principal
- Crear un service principal para trabajo local: si tu código corre en tu laptop, no necesitás un service principal. Hacé
az loginy dejá queDefaultAzureCredentialuse esa sesión. El mismo código funciona después en Azure sin cambiar una línea. - Usar roles a través de un grupo de Entra con una managed identity: esto empeora el problema del caché de 24 horas. La corrección de Microsoft es poner el permiso directamente sobre la user-assigned identity, no sobre un grupo.
- Dejar el
--create-passwordpor defecto enaz ad sp create-for-rbac: ese comando crea un client secret automáticamente salvo que vos le digas lo contrario con--create-password false. Si tu intención era usar federación OIDC, terminás con un secreto de más dando vueltas. - No revisar el formato del sub claim al migrar a un repo nuevo de GitHub: copiar la credencial federada de un workflow viejo sin chequear si el repositorio es posterior al 15 de julio de 2026 rompe la autenticación sin aviso previo.
Preguntas Frecuentes
¿Cuál es la diferencia entre managed identity y service principal en Azure?
La diferencia está en quién administra la credencial: Azure crea, guarda y rota la credencial de una managed identity sin que puedas verla, mientras que en un service principal tradicional vos generás y rotás el secreto o certificado. Técnicamente, toda managed identity es un service principal especial en Entra ID.
¿Cuándo conviene usar managed identity en vez de service principal?
Conviene usar managed identity siempre que tu código corra en cómputo de Azure que la soporte, como VMs, App Service o Azure Kubernetes. Elimina el riesgo de secretos filtrados y de credenciales que expiran sin aviso.
¿Se puede usar una managed identity fuera de Azure, por ejemplo en GitHub Actions?
No directamente: una managed identity solo sirve a workloads que corren sobre recursos de Azure. Para GitHub Actions hay que federar un app registration o una user-assigned identity con el proveedor OIDC de GitHub, usando issuer https://token.actions.githubusercontent.com.
¿Qué es mejor, identidad asignada por el sistema o asignada por el usuario?
User-assigned es mejor cuando varios recursos comparten el mismo acceso o cuando los recursos se crean y destruyen con frecuencia, porque reduce la cantidad de asignaciones de rol necesarias. System-assigned conviene cuando el permiso tiene que terminar exactamente cuando se borra el recurso.
¿Cuánto dura un client secret de un service principal en Azure?
Un client secret dura como máximo 24 meses, aunque Microsoft recomienda rotarlo antes de los 12. El comando az ad sp create-for-rbac usa por defecto un año de validez a través de su parámetro --years.
Conclusión
La regla práctica es corta: si tu código corre en Azure, usá managed identity y elegí user-assigned cuando haya recursos que compartan acceso o que rote seguido. Si corre en GitHub Actions, on-premises u otra nube, federá un service principal con OIDC y evitá el client secret. Si no sabés por dónde empezar, agarrá un workload que todavía use un secreto guardado a mano, migralo a managed identity o a credencial federada, y después borrá ese secreto. Es el cambio con menor esfuerzo y mayor reducción de riesgo que vas a hacer esta semana.






