La lección anterior dejó las identidades de Contoso Airlines creadas y gobernadas, pero con una carencia deliberada: Contoso-Desarrollo existe y todavía no puede hacer absolutamente nada, mientras que Marta Ríos es Propietaria de todo porque fue quien creó la suscripción. Ni una cosa ni la otra son aceptables. Hoy montas el sistema que decide qué puede hacer cada identidad sobre cada recurso: el control de acceso basado en roles de Azure, o RBAC. Y en la segunda mitad resuelves el problema que arrastramos desde el módulo 2: app-contoso-reservas-pro guarda hoy una clave de cuenta de almacenamiento y una cadena de conexión en sus ajustes de aplicación. Al terminar la lección, la aplicación se autenticará contra sttarjetascontosopro y db-reservas sin una sola contraseña en ningún sitio, gracias a las identidades administradas. Es, probablemente, la mejora de seguridad con mejor relación esfuerzo/beneficio de todo el curso.
Contenido
- Cómo autoriza Azure: la tríada de la asignación de rol
- Ámbitos y herencia por la jerarquía
- Roles integrados imprescindibles
- La trampa: Colaborador no da acceso a los datos
- Roles personalizados: "Operador de Reservas de Contoso"
- Denegación de asignaciones
- Mínimo privilegio aplicado a los grupos de Contoso
- Diagnosticar por qué alguien no tiene acceso
- Identidades administradas: qué son y qué eliminan
- Asignadas por el sistema frente a asignadas por el usuario
- El flujo del token: IMDS por dentro
- Contoso sin contraseñas: almacenamiento y base de datos
- Errores Comunes y Consejos
- Ejercicios
- Conclusión
- Cómo autoriza Azure: la tríada de la asignación de rol
Cuando alguien llama a la API de Azure Resource Manager, ocurren dos cosas en orden: Entra ID autentica (¿quién eres?) y RBAC autoriza (¿puedes hacer esto?). Una asignación de rol es siempre la unión de tres elementos, y si falta uno no hay acceso.
flowchart LR
A["ENTIDAD DE SEGURIDAD<br/>Contoso-Desarrollo"] --> D{{"ASIGNACION<br/>DE ROL"}}
B["DEFINICION DE ROL<br/>Colaborador"] --> D
C["AMBITO<br/>rg-contoso-reservas-dev"] --> D
D --> E["El grupo Contoso-Desarrollo puede<br/>gestionar recursos, y solo dentro<br/>del grupo de recursos de desarrollo"]
La entidad de seguridad es a quién (usuario, grupo, entidad de servicio o identidad administrada); la definición de rol es qué (una colección de operaciones permitidas en Actions y restadas en NotActions); y el ámbito es dónde (el nivel de la jerarquía sobre el que aplica).
az role assignment create \
--assignee-object-id $(az ad group show --group "Contoso-Desarrollo" --query id -o tsv) \
--assignee-principal-type Group \
--role "Contributor" \
--scope "/subscriptions/$SUB_DEV/resourceGroups/rg-contoso-reservas-dev"Usar --assignee-object-id con --assignee-principal-type en lugar de --assignee evita una consulta extra a Graph y, sobre todo, evita el fallo intermitente de las asignaciones a identidades recién creadas, cuya propagación en el directorio tarda unos segundos.
- Ámbitos y herencia por la jerarquía
RBAC se hereda hacia abajo por la jerarquía de Azure Resource Manager que viste en 01-05: grupo de administración (mg-contoso) → suscripción (Contoso Airlines - Producción) → grupo de recursos (rg-contoso-reservas-pro) → recurso (app-contoso-reservas-pro).
Quien es Lector en la suscripción es Lector en todos sus grupos de recursos y en todos los recursos de dentro. Los permisos son acumulativos y solo suman: no existe la "denegación por rol", así que dar Lector en un grupo de recursos a quien ya es Colaborador de la suscripción no le quita nada.
El grupo de administración se reserva para roles transversales de gobierno (Lector para auditoría) y alcanza a todas las suscripciones; la suscripción, para administración de plataforma; el recurso, para excepciones puntuales difíciles de mantener. Contoso asigna casi todo a nivel de grupo de recursos, que coincide con el ciclo de vida de cada carga de trabajo. Y siempre a grupos de Entra ID, no a personas: con cuatro grupos y cuatro grupos de recursos hay 16 combinaciones posibles y ninguna se rehace cuando alguien cambia de equipo; con asignaciones individuales, cada alta y cada baja es una revisión manual de toda la suscripción. Hay un límite duro que además lo obliga: 4.000 asignaciones de rol por suscripción, y las empresas que asignan a personas lo alcanzan.
- Roles integrados imprescindibles
Azure trae más de 400 roles integrados. Estos son los que se usan a diario:
| Rol | Plano de gestión | Plano de datos | Puede asignar roles | Uso típico |
|---|---|---|---|---|
| Propietario | Total | Según el servicio | Sí | Solo con PIM, nunca permanente |
| Colaborador | Total | No | No | Crear y gestionar recursos |
| Lector | Solo lectura | No | No | Auditoría, soporte de primer nivel |
| Administrador de acceso de usuario | Solo permisos | No | Sí | Delegar la gestión de accesos |
| Colaborador de datos de Blob Storage | No | Leer, escribir, borrar blobs | No | Aplicaciones que suben tarjetas |
| Lector de datos de Blob Storage | No | Leer blobs | No | Procesos de solo consulta |
| Usuario de Key Vault Secrets | No | Leer valores de secretos | No | Aplicaciones que consumen secretos |
| Responsable de Key Vault Secrets | No | Crear y gestionar secretos | No | Marta gestionando el almacén |
| Colaborador de máquina virtual | Gestionar VMs | No (no da SSH) | No | Operación de cómputo |
La diferencia entre Propietario y Colaborador se reduce a una sola cosa, pero enorme: Propietario puede asignar roles, es decir, puede darse a sí mismo y a cualquiera cualquier permiso. Por eso es el rol que menos gente debe tener y el candidato número uno para PIM (04-01).
- La trampa: Colaborador no da acceso a los datos
Este es el punto que más confusión genera en todo RBAC, y conviene entenderlo con el caso concreto.
Diego Salas es Colaborador de rg-contoso-reservas-pro. Con ese rol puede ver sttarjetascontosopro, cambiar su nivel de acceso, su redundancia y su firewall, e incluso eliminar la cuenta de almacenamiento entera con las tarjetas de embarque de dos años dentro. Y no puede leer un solo blob del contenedor tarjetas-embarque.
No es un error de configuración: Azure tiene dos planos. El plano de gestión (management.azure.com) crea, configura y borra recursos. El plano de datos (<cuenta>.blob.core.windows.net, <vault>.vault.azure.net) lee y escribe el contenido. Colaborador cubre el primero por completo y el segundo nada.
# Diego puede hacer esto (plano de gestion)
az storage account show -n sttarjetascontosopro -g rg-contoso-reservas-pro
# Y esto FALLA con AuthorizationPermissionMismatch (plano de datos)
az storage blob list --account-name sttarjetascontosopro -c tarjetas-embarque --auth-mode loginLa consecuencia no es una molestia, es la base del mínimo privilegio: Marta Ríos puede administrar la infraestructura sin poder leer los datos personales de los pasajeros, algo que el RGPD agradece y que además reduce el daño si le roban la sesión. Y hay un matiz importante: mientras existan claves de cuenta, un Colaborador puede leerlas (listKeys) y con ellas acceder a los datos, saltándose todo lo anterior. Por eso Contoso desactivará la autenticación por clave —lo verás en el apartado 12— y por eso las claves y las SAS del módulo 2 van a desaparecer.
- Roles personalizados: "Operador de Reservas de Contoso"
Contoso-Operaciones necesita algo que ningún rol integrado ofrece: reiniciar la aplicación web cuando se cuelga y consultar métricas, sin poder cambiar la configuración ni borrar nada. Eso es un rol personalizado.
{
"Name": "Operador de Reservas de Contoso",
"Description": "Reinicia la aplicacion web y consulta metricas; no modifica configuracion ni elimina recursos.",
"IsCustom": true,
"Actions": [
"Microsoft.Web/sites/read",
"Microsoft.Web/sites/restart/action",
"Microsoft.Web/sites/slots/read",
"Microsoft.Web/sites/slotsswap/action",
"Microsoft.Insights/metrics/read",
"Microsoft.Insights/metricDefinitions/read",
"Microsoft.Resources/subscriptions/resourceGroups/read"
],
"NotActions": [
"Microsoft.Web/sites/config/list/action"
],
"DataActions": [],
"NotDataActions": [],
"AssignableScopes": [
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-contoso-reservas-pro"
]
}Cada bloque importa:
Actions: operaciones del plano de gestión permitidas, con el formatoProveedor/tipoRecurso/operación. Aquí, leer sitios, reiniciarlos, intercambiar ranuras (para promoverpreproduccion) y consultar métricas.NotActions: se restan deActions.config/list/actiondevuelve los ajustes de la aplicación, que incluyen cadenas de conexión: la resta lo deja explícito y documentado.DataActions/NotDataActions: el equivalente para el plano de datos, vacías a propósito, porque operaciones no necesita leer tarjetas de embarque. YAssignableScopes: dónde se puede asignar el rol; limitarlo al grupo de recursos de producción impide aplicarlo por error a toda la suscripción.
az role definition create --role-definition ./rol-operador-reservas.json
az role assignment create \
--assignee-object-id $(az ad group show --group "Contoso-Operaciones" --query id -o tsv) \
--assignee-principal-type Group \
--role "Operador de Reservas de Contoso" \
--scope "/subscriptions/$SUB_PRO/resourceGroups/rg-contoso-reservas-pro"Antes de crear un rol personalizado, busca si ya existe uno integrado: az role definition list --query "[?contains(roleName,'Website')].roleName" -o tsv. Los personalizados hay que mantenerlos cuando Azure añade operaciones nuevas, y ese mantenimiento es real. El límite es de 5.000 roles personalizados por inquilino, pero el problema práctico llega mucho antes, en forma de catálogo inmanejable.
- Denegación de asignaciones
Existe un mecanismo que bloquea operaciones aunque un rol las permita: la denegación de asignaciones, que siempre gana frente a cualquier concesión. No se puede crear directamente por CLI ni portal; la generan servicios de Azure como Blueprints o las implementaciones administradas de aplicaciones. Se menciona aquí para que, si alguna vez ves un acceso denegado siendo Propietario, sepas dónde mirar: az role assignment list-deny.
- Mínimo privilegio aplicado a los grupos de Contoso
| Grupo | Ámbito | Rol | Razón |
|---|---|---|---|
Contoso-Infraestructura |
Suscripción de producción | Colaborador y Administrador de acceso de usuario, ambos aptos vía PIM | Gestiona todo, sin privilegio en reposo |
Contoso-Desarrollo |
rg-contoso-reservas-dev |
Colaborador | Libertad total en desarrollo |
Contoso-Desarrollo |
Suscripción de producción | Lector | Diagnosticar sin poder tocar |
Contoso-Operaciones |
rg-contoso-reservas-pro |
Operador de Reservas de Contoso | Reiniciar y observar |
Contoso-DBA-Reservas |
sql-contoso-reservas-pro |
Colaborador de SQL Server + admin de Entra en el servidor | Administrar la base sin tocar el resto |
SUB_PRO=$(az account show --query id -o tsv)
DEV=$(az ad group show --group "Contoso-Desarrollo" --query id -o tsv)
# Lector en produccion para desarrollo: ven los problemas, no los provocan
az role assignment create --assignee-object-id $DEV --assignee-principal-type Group \
--role "Reader" --scope "/subscriptions/$SUB_PRO"
# Auditoria del reparto actual, incluyendo lo heredado
az role assignment list --all --include-inherited \
--query "[].{Quien:principalName, Rol:roleDefinitionName, Ambito:scope}" -o tableRegla práctica de Contoso: Propietario solo mediante PIM y con aprobación, Colaborador en producción solo para infraestructura, y todo el que "solo necesita mirar" recibe Lector. El 90 % de las peticiones de acceso se resuelven con Lector más un rol de datos concreto.
- Diagnosticar por qué alguien no tiene acceso
Cuando alguien dice "no puedo", sigue este orden:
# 1. Que tiene esa persona, incluyendo herencia y pertenencia a grupos
az role assignment list --assignee [email protected] \
--all --include-inherited --include-groups -o table
# 2. Que hay asignado en el recurso concreto
az role assignment list --scope "/subscriptions/$SUB_PRO/resourceGroups/rg-contoso-reservas-pro" -o table
# 3. Que accion exacta exige la operacion que falla
az provider operation show --namespace Microsoft.Storage --query "resourceTypes[].operations[].name" -o tsvSi la CLI no aclara nada, en el portal está Control de acceso (IAM) → Comprobar acceso, que muestra el acceso efectivo de una identidad sobre ese recurso con el origen de cada permiso. Y si el acceso se perdió, el registro de actividad dice quién retiró la asignación y cuándo: filtra por la operación Microsoft.Authorization/roleAssignments/delete.
Cuatro causas explican casi todos los casos: (1) el rol es de gestión y la operación es de datos —apartado 4—; (2) el ámbito es más estrecho de lo que se creía; (3) la asignación se hizo en otra suscripción; (4) la asignación es correcta pero el token del usuario es anterior y hay que cerrar sesión y volver a entrar. La propagación de RBAC tarda hasta cinco minutos, y de vez en cuando algo más.
- Identidades administradas: qué son y qué eliminan
Ahora el segundo problema. app-contoso-reservas-pro tiene hoy, en sus ajustes de aplicación, una clave de sttarjetascontosopro y una cadena de conexión con usuario y contraseña de db-reservas. Esos secretos existen en al menos cuatro sitios: la configuración de la aplicación, el fichero .env del portátil de Diego, el historial del repositorio y un correo de hace ocho meses. Nunca han rotado. Si alguno se filtra, el atacante lee las tarjetas de embarque de todos los pasajeros.
Una identidad administrada es una entidad de servicio de Entra ID cuyo ciclo de vida y credenciales los gestiona Azure: el recurso obtiene tokens sin que exista una contraseña que alguien pueda copiar, escribir en un fichero o filtrar. No hay credencial que rotar porque no hay credencial. Es gratuita y está disponible en App Service, Functions, VMs, VMSS, Container Apps, AKS, Data Factory, Logic Apps y prácticamente todo lo demás.
- Asignadas por el sistema frente a asignadas por el usuario
| Asignada por el sistema | Asignada por el usuario | |
|---|---|---|
| Ciclo de vida | Ligado al recurso: nace y muere con él | Recurso independiente, se elimina aparte |
| Relación | 1:1 con un recurso | 1:N, compartida por varios recursos |
| Al recrear el recurso | Nuevo ID: hay que rehacer las asignaciones | El mismo ID: los permisos se conservan |
| Preasignar permisos | No (el ID no existe aún) | Sí, antes de crear el recurso |
| Cuándo usarla | Aplicación única y estable | Flotas (VMSS), infraestructura como código, despliegues azul-verde |
Contoso usa la asignada por el sistema para app-contoso-reservas-pro, porque es una aplicación única. Para vmss-api-disponibilidad-pro, donde las instancias se crean y destruyen con el autoescalado, usa una asignada por el usuario llamada id-contoso-api-pro: los permisos se conceden una vez a la identidad y todas las instancias los heredan, presentes y futuras. Si además vas a desplegar con Bicep (05-06), la asignada por el usuario evita el problema del huevo y la gallina: se crea primero, se le dan permisos y luego se asocia a los recursos.
- El flujo del token: IMDS por dentro
sequenceDiagram
participant App as app-contoso-reservas-pro
participant IMDS as Punto de conexion local<br/>(IMDS 169.254.169.254)
participant Entra as Microsoft Entra ID
participant St as sttarjetascontosopro
App->>IMDS: GET /metadata/identity/oauth2/token<br/>?resource=https://storage.azure.com/
IMDS->>Entra: Solicita token para la identidad del recurso
Entra-->>IMDS: Token de acceso JWT (valido ~24 h)
IMDS-->>App: Token de acceso
App->>St: GET /tarjetas-embarque/BP-4471.pdf<br/>Authorization: Bearer <token>
St->>St: Valida el token y comprueba RBAC
St-->>App: PDF de la tarjeta de embarque
Lo esencial de este flujo: la petición del token viaja a 169.254.169.254, una dirección link-local no enrutable que solo responde dentro de la propia máquina virtual o instancia. Ningún atacante externo puede pedir ese token porque no puede llegar a ese punto de conexión; y como todo ocurre dentro del recurso, no hay secreto que transmitir. En App Service el mecanismo es equivalente, expuesto mediante las variables IDENTITY_ENDPOINT e IDENTITY_HEADER, que el SDK usa automáticamente.
- Contoso sin contraseñas: almacenamiento y base de datos
Primero se activa la identidad y se guarda su identificador de objeto:
RG="rg-contoso-reservas-pro"; APP="app-contoso-reservas-pro"
PRINCIPAL=$(az webapp identity assign -g $RG -n $APP --query principalId -o tsv)Después se le concede acceso a los datos, con el rol más estrecho posible y en el ámbito más estrecho posible —el contenedor, no la cuenta:
ST_ID=$(az storage account show -n sttarjetascontosopro -g $RG --query id -o tsv)
az role assignment create --assignee-object-id $PRINCIPAL --assignee-principal-type ServicePrincipal \
--role "Storage Blob Data Contributor" \
--scope "$ST_ID/blobServices/default/containers/tarjetas-embarque"
# Y ahora lo importante: se cierra la puerta antigua
az storage account update -n sttarjetascontosopro -g $RG --allow-shared-key-access falseEsa última línea es la que convierte el ejercicio en una mejora real: con --allow-shared-key-access false, las claves de cuenta y las SAS del módulo 2 dejan de funcionar, y el único acceso posible pasa por identidades de Entra ID con su rol. Antes de ejecutarla hay que asegurarse de que ningún proceso heredado las use, porque el corte es inmediato.
Para db-reservas, la base ya tiene autenticación solo con Entra ID sobre el grupo Contoso-DBA-Reservas (03-02). Falta crear el usuario de la aplicación, ejecutando esto conectado como administrador de Entra ID:
CREATE USER [app-contoso-reservas-pro] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [app-contoso-reservas-pro];
ALTER ROLE db_datawriter ADD MEMBER [app-contoso-reservas-pro];
GRANT EXECUTE ON SCHEMA::dbo TO [app-contoso-reservas-pro];El nombre del usuario es exactamente el del recurso de App Service, que es como se llama su identidad administrada. Nótese que no se le da db_owner: leer, escribir y ejecutar procedimientos es todo lo que la aplicación necesita, y con eso no puede alterar el esquema.
En el código, todo esto se reduce a una clase. DefaultAzureCredential prueba en orden las credenciales disponibles —variables de entorno, identidad administrada, Azure CLI, Visual Studio— de modo que el mismo código funciona en el portátil de Diego y en producción sin cambios ni secretos:
using Azure.Identity;
using Azure.Storage.Blobs;
using Microsoft.Data.SqlClient;
// Una sola instancia, reutilizada: la credencial cachea los tokens internamente
var credencial = new DefaultAzureCredential();
// Almacenamiento: sin clave de cuenta ni SAS, solo el nombre de la cuenta
var blobs = new BlobServiceClient(
new Uri("https://sttarjetascontosopro.blob.core.windows.net"),
credencial);
var contenedor = blobs.GetBlobContainerClient("tarjetas-embarque");
await contenedor.UploadBlobAsync("BP-4471.pdf", flujoPdf);
// SQL: cadena de conexion SIN usuario ni contrasena
var cadena = "Server=tcp:sql-contoso-reservas-pro.database.windows.net,1433;"
+ "Database=db-reservas;Authentication=Active Directory Default;Encrypt=True;";
await using var conexion = new SqlConnection(cadena);
await conexion.OpenAsync();El equivalente en Python es literalmente el mismo patrón: DefaultAzureCredential() se pasa como parámetro credential de BlobServiceClient, y no aparece ninguna clave por ningún lado. Compara las dos cadenas de conexión: la del módulo 3 llevaba usuario y contraseña; esta no lleva nada. No hay secreto que rotar, filtrar ni revocar. Los secretos que sí siguen existiendo —claves de APIs de terceros, el certificado de la pasarela de pago— son el tema de la lección siguiente.
Errores Comunes y Consejos
- Dar Colaborador y esperar acceso a los datos. Es la incidencia número uno. Los roles de datos son otros (apartado 4).
- Asignar Propietario "para que no moleste", o asignar roles a personas y no a grupos, o subir al ámbito de suscripción por comodidad. Los tres son la misma pereza y los tres se pagan en el mes doce.
- Dejar las claves de cuenta activas tras pasar a identidad administrada. Si
allow-shared-key-accesssigue entrue, la puerta antigua sigue abierta y cualquier Colaborador puede usarla. - Crear un rol personalizado antes de buscar el integrado. Hay más de 400; casi siempre existe uno que sirve, y el personalizado hay que mantenerlo.
- Olvidar que la identidad asignada por el sistema muere con el recurso. Si recreas la aplicación, sus asignaciones de rol quedan huérfanas. Y ten paciencia con la propagación: RBAC tarda hasta cinco minutos, y el token del usuario hasta que vuelva a iniciar sesión.
- Consejo: crea una sola instancia de
DefaultAzureCredentialy reutilízala. Una por petición dispara la latencia y puede provocar limitación de solicitudes. - Consejo: revisa trimestralmente
az role assignment list --allbuscando asignaciones huérfanas (identidades borradas aparecen como GUID sin nombre) y elimínalas.
Ejercicios
Ejercicio 1: repartir permisos en Contoso Millas
El proyecto "Contoso Millas" (centro-coste=CC-2077) tiene rg-contoso-millas-pro y rg-contoso-millas-dev. Participan: tres desarrolladores que despliegan en desarrollo y necesitan diagnosticar producción; un analista que solo consulta métricas y costes; una aplicación web que lee y escribe blobs en stmillascontosopro; y Marta Ríos, que administra la infraestructura.
- Indica entidad, rol y ámbito para cada caso, en formato de tabla.
- ¿Cuál de esas cuatro entidades no debe ser un usuario, y qué debe ser?
- ¿Qué asignación pondrías bajo PIM y por qué?
Ejercicio 2: escribir un rol personalizado
Contoso necesita un rol "Soporte de Reservas de Contoso" que permita leer cualquier recurso del grupo de producción, reiniciar máquinas virtuales y abrir tickets de soporte, pero nunca leer secretos de Key Vault ni datos de blobs.
- Escribe el
jsonde la definición conActions,NotActions,DataActionsyAssignableScopes. - ¿Por qué
DataActionsvacío ya impide leer blobs, aunque no aparezca nada enNotDataActions? - ¿Qué comando usarías para averiguar el nombre exacto de la acción de reinicio de una VM?
Ejercicio 3: eliminar la última contraseña
La API de Disponibilidad corre en vmss-api-disponibilidad-pro y guarda en un fichero de configuración la clave de stoperacionescontosopro y la contraseña de cosmos-contoso-tarifas-pro.
- ¿Qué tipo de identidad administrada corresponde aquí y por qué no la otra?
- Enumera los pasos, con los comandos, para eliminar ambos secretos.
- Un desarrollador dice que "en local no funcionará porque no hay identidad administrada". ¿Qué le respondes?
Soluciones
Solución 1:
- Grupo
Contoso-Millas-Desarrollo: Colaborador enrg-contoso-millas-devy Lector enrg-contoso-millas-pro. Analista: Lector más Lector de Cost Management en la suscripción. Aplicación web: Colaborador de datos de Blob Storage en el contenedor destmillascontosopro, nunca en la cuenta entera. Marta, a través deContoso-Infraestructura: Colaborador en la suscripción, apto vía PIM. - La aplicación web: debe ser una identidad administrada, no un usuario ni una entidad de servicio con secreto. Ninguna aplicación necesita una contraseña en Azure.
- Las de Marta, y cualquier Propietario o Administrador de acceso de usuario: son las que permiten escalar privilegios, y con PIM no existen en reposo. El acceso de Lector de desarrollo sobre producción no lo necesita: es de solo lectura y su uso es cotidiano.
Solución 2:
Actions:*/read,Microsoft.Compute/virtualMachines/restart/action,Microsoft.Support/*.NotActions:Microsoft.KeyVault/vaults/secrets/read,Microsoft.Storage/storageAccounts/listKeys/action(crítica: sin ella,*/readno la incluye pero conviene dejarla explícita, y evita obtener claves si se ampliaran las acciones).DataActions:[].NotDataActions:[].AssignableScopes: el identificador derg-contoso-reservas-pro.- Porque el plano de datos deniega por defecto: solo se concede lo que aparece explícitamente en
DataActions.NotDataActionssirve para restar de un conjunto concedido, y aquí no hay ninguno. SinDataActions, no hay acceso a datos, punto. az provider operation show --namespace Microsoft.Compute --query "resourceTypes[?name=='virtualMachines'].operations[].name", o el mismo comando filtrando porrestart.
Solución 3:
- Asignada por el usuario (
id-contoso-api-pro). En un conjunto de escalado las instancias nacen y mueren constantemente; con identidad asignada por el sistema, cada instancia tendría su propio identificador y habría que asignarle permisos al crearse, lo cual es inviable con autoescalado. Con la asignada por el usuario se conceden los permisos una vez y todas las instancias los heredan. - Crear la identidad (
az identity create -g rg-contoso-reservas-pro -n id-contoso-api-pro); asociarla al conjunto (az vmss identity assign --identities); asignarle Colaborador de datos de Blob Storage sobre el contenedor destoperacionescontosoproy Colaborador de datos integrado de Cosmos DB sobre la basecatalogo(conaz cosmosdb sql role assignment create, que es el sistema RBAC propio de Cosmos); desactivar el acceso por clave en el almacenamiento con--allow-shared-key-access falsey deshabilitar las claves de Cosmos con--disable-key-based-metadata-write-access; y por último eliminar el fichero de configuración y purgar el secreto del historial del repositorio. - Que sí funciona:
DefaultAzureCredentialrecorre una cadena de proveedores y, si no encuentra identidad administrada, usa la sesión de Azure CLI (az login) o la de Visual Studio Code. El código es idéntico en local y en producción; lo único que cambia es de dónde sale el token. Basta con darle a su usuario el rol de datos correspondiente en el entorno de desarrollo.
Conclusión
Ya sabes cómo autoriza Azure. Una asignación de rol es siempre una tríada —entidad de seguridad, definición de rol y ámbito— que se hereda hacia abajo por la jerarquía grupo de administración, suscripción, grupo de recursos y recurso, con permisos que solo suman. Conoces los roles integrados que se usan de verdad y la diferencia decisiva entre Propietario y Colaborador: asignar roles. Y tienes clara la trampa que más incidencias genera: Colaborador no da acceso a los datos, porque el plano de gestión y el plano de datos son universos separados, de modo que Diego puede borrar sttarjetascontosopro entera y no puede leer un solo PDF de dentro. Has escrito el rol personalizado "Operador de Reservas de Contoso" entendiendo Actions, NotActions, DataActions y AssignableScopes, sabes que existe la denegación de asignaciones y has repartido los permisos de los cuatro grupos de Contoso con mínimo privilegio real, además de un procedimiento ordenado para diagnosticar por qué alguien no tiene acceso.
En la segunda mitad has eliminado el problema de raíz. Las identidades administradas son entidades de servicio cuyas credenciales gestiona Azure, distingues las asignadas por el sistema —una por recurso, mueren con él— de las asignadas por el usuario —compartidas, con permisos preasignables, obligatorias en vmss-api-disponibilidad-pro—, y entiendes el flujo del token contra el punto de conexión local IMDS en 169.254.169.254, no enrutable desde fuera. Con eso, app-contoso-reservas-pro accede a sttarjetascontosopro con el rol Colaborador de datos de Blob Storage y a db-reservas como usuario externo con db_datareader y db_datawriter, se ha desactivado el acceso por clave compartida y DefaultAzureCredential hace que el mismo código funcione en el portátil y en producción sin un solo secreto.
Pero no todos los secretos desaparecen así. Contoso sigue teniendo la clave de la pasarela de pago, el token del proveedor de datos meteorológicos, el certificado TLS de contosoairlines.example y unas cuantas cadenas de conexión de sistemas heredados, hoy repartidas entre ajustes de aplicación, el repositorio y un documento compartido. En la siguiente lección, Azure Key Vault, centralizarás todo eso en kv-contoso-pro dentro de rg-contoso-seguridad-pro, con eliminación temporal, protección contra purga, permisos por RBAC y punto de conexión privado, y harás que la aplicación los lea con la misma identidad administrada de hoy mediante referencias @Microsoft.KeyVault(...). Es el momento en que las contraseñas desaparecen también del despliegue.
Curso de Azure
Módulo 1: Introducción a Azure
- ¿Qué es Azure?
- Modelos de servicio, regiones y zonas de disponibilidad
- Crear y configurar tu cuenta de Azure
- Recorrido por el portal de Azure
- Azure Resource Manager: suscripciones, grupos de recursos y etiquetas
- Azure CLI, PowerShell y Cloud Shell
Módulo 2: Servicios principales de Azure
- Máquinas virtuales de Azure
- Escalado y alta disponibilidad del cómputo
- Azure App Service
- Azure Storage: blobs, archivos, colas y tablas
- Redes en Azure: redes virtuales, subredes y NSG
- Conectividad híbrida y entrega global
Módulo 3: Bases de datos de Azure
- Elegir el servicio de datos adecuado
- Azure SQL Database
- Azure Cosmos DB
- Azure Database for MySQL
- Azure Database for PostgreSQL
- Analítica de datos: Data Lake, Data Factory y Synapse
Módulo 4: Seguridad en Azure
- Microsoft Entra ID y gestión de identidades
- RBAC e identidades administradas
- Azure Key Vault
- Protección DDoS y firewall de aplicaciones web
- Microsoft Defender for Cloud
- Gobernanza y cumplimiento con Azure Policy
Módulo 5: Azure DevOps
- Introducción a Azure DevOps
- Azure Repos
- Azure Pipelines: integración continua
- Despliegue continuo con entornos y aprobaciones
- Azure Artifacts
- Infraestructura como código con Bicep
Módulo 6: Servicios avanzados de Azure
- Contenedores en Azure: Container Registry y Container Apps
- Azure Kubernetes Service (AKS)
- Azure Functions
- Azure Logic Apps
- Mensajería y eventos: Service Bus, Event Grid y Event Hubs
- Servicios de IA de Azure
Módulo 7: Monitoreo y gestión
- Azure Monitor: métricas, alertas y paneles
- Log Analytics y consultas KQL
- Application Insights
- Azure Automation y runbooks
- Copias de seguridad y recuperación ante desastres
Módulo 8: Gestión y optimización de costos
- Calculadora de precios y estimación de costes
- Azure Cost Management: análisis, presupuestos y alertas
- Reservas, planes de ahorro y Azure Hybrid Benefit
- Azure Advisor
- Estrategias de optimización y cultura FinOps
