Diferencia entre IAM User e IAM Role: cuándo usar cada uno en AWS
Una de las confusiones más comunes al empezar a operar en AWS es decidir entre un IAM User y un IAM Role para dar acceso a una aplicación. El error clásico: crear un IAM User, generar credenciales de acceso estáticas, y pegarlas directamente en el código o en un archivo de configuración dentro de una instancia EC2. Funciona, pero es una bomba de tiempo operacional y de seguridad.
TL;DR: IAM User vs IAM Role
| Característica | IAM User | IAM Role |
|---|---|---|
| Identidad para | Personas humanas o sistemas externos sin soporte de roles | Servicios AWS, aplicaciones, cuentas cruzadas, identidades federadas |
| Credenciales | Estáticas (Access Key ID + Secret Access Key) | Temporales, rotadas automáticamente por STS |
| Gestión de secretos | Manual — rotación, revocación, almacenamiento seguro | Automática — no hay secretos que gestionar |
| EC2 accediendo a S3 | No recomendado | Recomendado (Instance Profile) |
| Riesgo de filtración | Alto si las claves se exponen en código o logs | Bajo — las credenciales expiran automáticamente |
Cómo funciona IAM: identidades, políticas y el modelo de confianza
IAM (Identity and Access Management) es el plano de control de permisos en AWS. Antes de elegir entre User y Role, hay que entender qué los diferencia a nivel estructural, no solo conceptual.
Un IAM User es una identidad permanente asociada a una persona o sistema. Tiene credenciales de larga duración: contraseña para la consola y/o Access Key ID + Secret Access Key para la API. Esas claves no expiran salvo que las rotes manualmente o las desactives. Son tuyas hasta que las borres.
Un IAM Role es una identidad que no tiene credenciales propias permanentes. En cambio, define una política de confianza (trust policy) que especifica quién puede asumir ese rol. Cuando una entidad asume el rol, AWS STS (Security Token Service) emite credenciales temporales: Access Key ID, Secret Access Key, y un Session Token con tiempo de expiración. La aplicación usa esas credenciales mientras son válidas, y STS las rota automáticamente.
- IAM User con claves estáticas: las credenciales son fijas. Si se filtran, el atacante tiene acceso indefinido hasta que las rotes manualmente.
- IAM Role con Instance Profile: EC2 solicita credenciales temporales al servicio de metadatos (IMDS). STS las emite con expiración automática. La aplicación nunca gestiona secretos.
- Trust Policy: el rol define explícitamente que
ec2.amazonaws.compuede asumirlo. Sin esa entrada, ninguna instancia puede usar el rol.
Diferencia entre IAM User e IAM Role: el modelo de credenciales
La diferencia operacional más importante no es conceptual — es el ciclo de vida de las credenciales.
Con un IAM User, tú eres responsable de rotar las claves, almacenarlas de forma segura, y revocarlas si se comprometen. En la práctica, las claves de acceso estáticas terminan en variables de entorno, archivos .env, repositorios de código, o AMIs. El historial de incidentes de seguridad en AWS está lleno de este patrón.
Con un IAM Role asignado a una instancia EC2 mediante un Instance Profile, las credenciales temporales están disponibles en el endpoint de metadatos de la instancia (http://169.254.169.254/latest/meta-data/iam/security-credentials/). El SDK de AWS las recupera automáticamente, las cachea, y las renueva antes de que expiren. Tu aplicación no necesita saber que existen credenciales — simplemente hace llamadas a la API y el SDK se encarga del resto.
Pensar en un IAM Role como una llave maestra que se autodestruye cada hora es más preciso que verlo como 'permisos sin contraseña'. El mecanismo de expiración es lo que lo hace seguro, no la ausencia de credenciales en sí.
Cuándo usar IAM User
Los IAM Users tienen casos de uso legítimos y bien definidos. El problema no es que existan, sino usarlos donde un Role es la opción correcta.
- Acceso humano a la consola de AWS: aunque AWS recomienda usar IAM Identity Center (SSO) para usuarios humanos en entornos de producción, un IAM User con MFA habilitado es válido para cuentas individuales o equipos pequeños.
- Sistemas externos que no pueden asumir roles: herramientas de CI/CD legacy, sistemas on-premises sin soporte de federación de identidad, o integraciones de terceros que requieren credenciales estáticas. En estos casos, usa IAM Users con permisos mínimos, rotación periódica de claves, y monitoreo de uso.
- Acceso programático desde fuera de AWS: cuando el origen no es un servicio AWS y no hay infraestructura para federar identidades.
Cuándo usar IAM Role — y cómo configurarlo para EC2 y S3
Para cualquier carga de trabajo que corre dentro de AWS — EC2, Lambda, ECS, EKS — un IAM Role es siempre la opción correcta. No hay excepciones razonables.
Para que una instancia EC2 acceda a S3, necesitas tres componentes: el rol, la política de permisos adjunta al rol, y el Instance Profile que vincula el rol a la instancia.
Paso 1: Crear el IAM Role con trust policy para EC2
# Crear el archivo de trust policy
cat > trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
# Crear el rol
aws iam create-role \
--role-name EC2S3ReadRole \
--assume-role-policy-document file://trust-policy.json \
--region us-east-1
Paso 2: Crear y adjuntar la política de permisos sobre S3
Aplica el principio de mínimo privilegio: si la aplicación solo necesita leer objetos de un bucket específico, no le des acceso de escritura ni acceso a todos los buckets.
# Crear la política de permisos
cat > s3-read-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::nombre-de-tu-bucket",
"arn:aws:s3:::nombre-de-tu-bucket/*"
]
}
]
}
EOF
# Crear la política en IAM
aws iam create-policy \
--policy-name EC2S3ReadPolicy \
--policy-document file://s3-read-policy.json
# Adjuntar la política al rol (reemplaza 123456789012 con tu Account ID)
aws iam attach-role-policy \
--role-name EC2S3ReadRole \
--policy-arn arn:aws:iam::123456789012:policy/EC2S3ReadPolicy
Paso 3: Crear el Instance Profile y asociarlo al rol
El Instance Profile es el contenedor que permite asociar un IAM Role a una instancia EC2. Son entidades distintas en IAM, aunque la consola de AWS los crea juntos automáticamente cuando usas la interfaz gráfica.
# Crear el Instance Profile
aws iam create-instance-profile \
--instance-profile-name EC2S3ReadProfile
# Agregar el rol al Instance Profile
aws iam add-role-to-instance-profile \
--instance-profile-name EC2S3ReadProfile \
--role-name EC2S3ReadRole
Paso 4: Asociar el Instance Profile a la instancia EC2
# Asociar a una instancia existente (reemplaza i-1234567890abcdef0 con tu Instance ID)
aws ec2 associate-iam-instance-profile \
--instance-id i-1234567890abcdef0 \
--iam-instance-profile Name=EC2S3ReadProfile \
--region us-east-1
Si estás lanzando una instancia nueva, puedes especificar el Instance Profile directamente en el parámetro --iam-instance-profile del comando aws ec2 run-instances.
Verificar que las credenciales están disponibles en la instancia
# Desde dentro de la instancia EC2
aws sts get-caller-identity
Si el Instance Profile está correctamente asociado, este comando devuelve el ARN del rol asumido, no un IAM User. Si ves un error de credenciales, verifica que el Instance Profile esté asociado y que el servicio de metadatos (IMDSv2) esté accesible.
- La aplicación llama al SDK de AWS sin gestionar credenciales explícitamente.
- El SDK consulta el proveedor de credenciales, que detecta el Instance Profile disponible.
- El SDK solicita credenciales temporales al endpoint de metadatos de la instancia (IMDS).
- IMDS devuelve credenciales STS con tiempo de expiración. El SDK las cachea y las renueva automáticamente.
- La llamada a S3 se autoriza contra la política adjunta al rol.
El error que todo el mundo comete: credenciales estáticas en EC2
El patrón de fallo más común tiene esta forma: el desarrollador crea un IAM User, genera un Access Key, y lo configura con aws configure dentro de la instancia EC2. Todo funciona en desarrollo. La instancia pasa a producción. Seis meses después, alguien hace un git log y encuentra las claves en un commit antiguo, o peor, en una AMI compartida.
El diagnóstico inicial suele ser incorrecto: 'las claves están en variables de entorno, no en el código'. Pero el problema real es que el SDK de AWS tiene una cadena de proveedores de credenciales con orden de precedencia. Si hay credenciales configuradas con aws configure (archivo ~/.aws/credentials), el SDK las usa antes de consultar el Instance Profile — incluso si el Instance Profile está correctamente configurado.
Esto significa que puedes tener un Instance Profile asociado a la instancia y aun así estar usando credenciales estáticas sin saberlo. Para verificar cuál identidad está usando realmente tu aplicación:
# Verificar la identidad activa desde la instancia
aws sts get-caller-identity
# Verificar si hay credenciales estáticas configuradas
cat ~/.aws/credentials
Si get-caller-identity devuelve un IAM User en lugar del ARN de un rol, tienes credenciales estáticas sobreescribiendo el Instance Profile. Elimina el archivo ~/.aws/credentials y las variables de entorno AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY si están definidas.
Diferencia entre IAM User e IAM Role: permisos de diagnóstico
Si necesitas verificar los permisos efectivos de un rol o depurar por qué una llamada a S3 falla con AccessDenied, estos comandos cubren los puntos de diagnóstico principales.
🔽 Comandos de diagnóstico IAM (click para expandir)
# Ver las políticas adjuntas al rol
aws iam list-attached-role-policies \
--role-name EC2S3ReadRole
# Ver el contenido de una política específica
aws iam get-policy-version \
--policy-arn arn:aws:iam::123456789012:policy/EC2S3ReadPolicy \
--version-id v1
# Ver la trust policy del rol
aws iam get-role \
--role-name EC2S3ReadRole \
--query 'Role.AssumeRolePolicyDocument'
# Verificar el Instance Profile asociado a la instancia
aws ec2 describe-instances \
--instance-ids i-1234567890abcdef0 \
--query 'Reservations[0].Instances[0].IamInstanceProfile' \
--region us-east-1
# Simular si el rol tiene permiso para una acción específica en S3
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:role/EC2S3ReadRole \
--action-names s3:GetObject \
--resource-arns arn:aws:s3:::nombre-de-tu-bucket/objeto-de-prueba.txt
El comando simulate-principal-policy es especialmente útil porque evalúa todas las políticas adjuntas al rol — incluyendo SCPs si la cuenta está bajo una AWS Organization — y devuelve si la acción resultaría en allowed o implicitDeny/explicitDeny. Un AccessDenied en producción con un rol que 'debería tener permisos' casi siempre es un SCP o una bucket policy que no se revisó.
Wrap-up: IAM User vs IAM Role — la regla operacional
La regla es simple: si la identidad es un servicio AWS corriendo dentro de AWS, usa un IAM Role. Si es una persona o un sistema externo sin soporte de federación, usa un IAM User con MFA y rotación de claves. No hay zona gris en el caso de EC2 accediendo a S3 — siempre es un Instance Profile con un IAM Role.
El siguiente paso natural es explorar la documentación oficial de Instance Profiles y considerar AWS IAM Identity Center si gestionas acceso humano a múltiples cuentas.
Glosario de términos clave
| Término | Definición operacional |
|---|---|
| IAM User | Identidad permanente en AWS con credenciales de larga duración. Diseñada para personas o sistemas externos. |
| IAM Role | Identidad asumible sin credenciales permanentes. Emite credenciales temporales via STS cuando es asumida. |
| Instance Profile | Contenedor que asocia un IAM Role a una instancia EC2. Entidad IAM separada del rol en sí. |
| Trust Policy | Política JSON adjunta a un rol que define qué entidades (servicios, cuentas, usuarios) pueden asumirlo. |
| STS (Security Token Service) | Servicio AWS que emite credenciales temporales cuando una entidad asume un rol. |
Comentarios
Publicar un comentario