Saltar al contenido

lección 4

IAM: el sistema de seguridad que no puedes ignorar

Users, groups, roles, policies y el principio de mínimo privilegio. IAM es la puerta de entrada a todo en AWS — un error aquí es una brecha de seguridad.

60 min

Si S3 es el corazón de tu data lake, IAM (Identity and Access Management) es el sistema inmunológico. Es lo que decide quién puede entrar, qué puede tocar y qué le está prohibido. Y te voy a ser brutalmente honesto: IAM es el servicio que más gente ignora, configura mal, y después llora cuando algo sale terriblemente mal.

Ojo con lo que este laboratorio no puede enseñarte. LocalStack, por defecto, no aplica IAM: acepta cualquier llamada venga de quien venga. Aplicarlo de verdad (ENFORCE_IAM=1) es una función de sus planes de pago. Así que aquí vas a aprender a escribir políticas, no a comprobar que funcionan — y esas son dos habilidades distintas. Para comprobarlas tienes tres caminos: el evaluador local del ejercicio 4 (la parte que sí puedes ejecutar hoy), el IAM Policy Simulator de la consola de AWS si algún día tienes cuenta, y CloudTrail, que te dice qué policy denegó qué llamada.

He visto personalmente tres incidentes graves causados por IAM mal configurado: una startup que dejó un bucket S3 público sin querer y filtraron datos de 2 millones de usuarios. Un equipo de datos que dio permisos de administrador a un pipeline automatizado y un bug borró tablas de producción. Y una empresa que nunca rotó las access keys y un ex-empleado accedió a datos confidenciales 6 meses después de irse. Todos estos incidentes eran 100% prevenibles con IAM bien configurado.

### El principio fundamental: mínimo privilegio

El principio de mínimo privilegio dice: cada identidad (usuario, servicio, aplicación) debe tener EXACTAMENTE los permisos que necesita para hacer su trabajo, y ni uno más. Es como las llaves de un hotel: el huésped tiene llave de su habitación, no de todas. El personal de limpieza tiene acceso a las habitaciones pero no a la caja fuerte. El director tiene acceso a todo. Cada rol tiene sus permisos.

En la práctica, esto significa que tu pipeline de ETL NO necesita permisos para borrar buckets. Solo necesita leer de un bucket y escribir en otro. Tu analista NO necesita poder crear instancias EC2. Solo necesita lanzar queries en Athena. Si das a todo el mundo permisos de administrador "para que no molesten con tickets", estás pidiendo un desastre.

### Los 4 conceptos clave de IAM

  1. 01.Users (Usuarios): identidades para personas reales. Cada persona del equipo tiene su propio user con credenciales únicas.
  2. 02.Groups (Grupos): conjuntos de users con los mismos permisos. Ejemplo: grupo "data-engineers" con permisos de Glue+S3+Athena.
  3. 03.Roles: identidades para SERVICIOS, no personas. Un role es lo que asumes temporalmente. Lambda asume un role, Glue asume un role, EC2 asume un role.
  4. 04.Policies (Políticas): documentos JSON que definen permisos específicos. Se adjuntan a users, groups o roles.

La relación es: las policies definen QUÉ se puede hacer. Los users/groups/roles definen QUIÉN puede hacerlo. Adjuntas policies a identidades para conectar el quién con el qué.

Las policies se adjuntan a users, groups o roles para definir permisos

### Anatomía de una Policy: el documento JSON

Las policies son documentos JSON con una estructura precisa. Cada policy tiene uno o más "statements" que dicen: este Effect (Allow/Deny) aplica a estas Actions sobre estos Resources bajo estas Conditions opcionales.

1import boto3
2import json
3
4iam = boto3.client('iam', endpoint_url='http://localhost:4566',
5 aws_access_key_id='test', aws_secret_access_key='test',
6 region_name='eu-west-1')
7
8# Policy para un pipeline ETL: leer de raw/, escribir en processed/
9etl_policy = {
10 "Version": "2012-10-17",
11 "Statement": [
12 {
13 "Sid": "LeerDatosRaw",
14 "Effect": "Allow",
15 "Action": [
16 "s3:GetObject",
17 "s3:ListBucket"
18 ],
19 "Resource": [
20 "arn:aws:s3:::datalake-empresa",
21 "arn:aws:s3:::datalake-empresa/raw/*"
22 ]
23 },
24 {
25 "Sid": "EscribirDatosProcesados",
26 "Effect": "Allow",
27 "Action": [
28 "s3:PutObject",
29 "s3:DeleteObject"
30 ],
31 "Resource": [
32 "arn:aws:s3:::datalake-empresa/processed/*"
33 ]
34 }
35 ]
36}
37
38# Crear la policy en IAM
39response = iam.create_policy(
40 PolicyName='ETLPipelinePolicy',
41 PolicyDocument=json.dumps(etl_policy),
42 Description='Permisos para pipeline ETL: leer raw, escribir processed'
43)
44print(f"Policy creada: {response['Policy']['Arn']}")

Una policy bien diseñada: solo permite lo estrictamente necesario

### Roles: identidades para servicios

Los roles son quizá el concepto más confuso de IAM para principiantes, pero son FUNDAMENTALES. Un role es una identidad que un servicio AWS "asume" temporalmente para obtener permisos. Piénsalo así: cuando Lambda ejecuta tu función, ¿con qué credenciales accede a S3? No tiene un usuario. Lo que tiene es un role. El role dice "Lambda puede asumir esta identidad, y esta identidad puede leer de S3".

La "trust policy" define QUIÉN puede asumir el role. La "permissions policy" define QUÉ puede hacer quien lo asume. Es un sistema de dos llaves: primero necesitas permiso para ponerte el disfraz (trust), luego el disfraz te da ciertos poderes (permissions).

1# Trust policy: permite que Lambda asuma este role
2trust_policy = {
3 "Version": "2012-10-17",
4 "Statement": [
5 {
6 "Effect": "Allow",
7 "Principal": {"Service": "lambda.amazonaws.com"},
8 "Action": "sts:AssumeRole"
9 }
10 ]
11}
12
13# Crear role para Lambda
14role_response = iam.create_role(
15 RoleName='LambdaETLRole',
16 AssumeRolePolicyDocument=json.dumps(trust_policy),
17 Description='Role para funciones Lambda de ETL'
18)
19print(f"Role creado: {role_response['Role']['Arn']}")
20
21# Adjuntar la policy de ETL al role
22iam.attach_role_policy(
23 RoleName='LambdaETLRole',
24 PolicyArn=response['Policy']['Arn'] # La policy que creamos antes
25)
26print("✅ Policy adjuntada al role")

Crear role con trust policy (quién lo asume) + adjuntar permissions policy (qué puede hacer)

### Users y Groups: organizar personas

1# Crear grupo de data engineers
2iam.create_group(GroupName='data-engineers')
3
4# Crear usuario y añadirlo al grupo
5iam.create_user(UserName='ana-garcia')
6iam.add_user_to_group(GroupName='data-engineers', UserName='ana-garcia')
7
8# Crear policy para el grupo (pueden usar Glue, Athena y S3)
9de_policy = {
10 "Version": "2012-10-17",
11 "Statement": [
12 {
13 "Effect": "Allow",
14 "Action": ["glue:*", "athena:*"],
15 "Resource": "*"
16 },
17 {
18 "Effect": "Allow",
19 "Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"],
20 "Resource": ["arn:aws:s3:::datalake-empresa*"]
21 }
22 ]
23}
24
25policy_resp = iam.create_policy(
26 PolicyName='DataEngineersPolicy',
27 PolicyDocument=json.dumps(de_policy)
28)
29
30# Adjuntar al grupo (todos los miembros heredan los permisos)
31iam.attach_group_policy(
32 GroupName='data-engineers',
33 PolicyArn=policy_resp['Policy']['Arn']
34)
35print("✅ Grupo configurado con permisos")

Los grupos simplifican la gestión: añades personas y heredan permisos automáticamente

Consejo de senior: NUNCA des permisos directamente a usuarios individuales. Siempre usa grupos. Si Ana deja la empresa, solo la sacas del grupo. Si contratas a 5 ingenieros nuevos, los añades al grupo y ya tienen todos los permisos correctos. Es la diferencia entre gestionar 50 llaves individuales vs 5 llaveros por departamento.

### Deny explícito: el candado que nadie puede abrir

En IAM, un Deny explícito SIEMPRE gana sobre un Allow. Es como un veto: aunque tengas 10 policies que te permiten algo, si UNA dice Deny, estás fuera. Esto es extremadamente útil para crear "guardarraíles" — barreras que nadie puede cruzar, ni siquiera un admin:

1# Guardarraíl: NADIE puede borrar el bucket de producción
2guardarrail = {
3 "Version": "2012-10-17",
4 "Statement": [
5 {
6 "Sid": "ProhibidoBorrarBucketProd",
7 "Effect": "Deny",
8 "Action": ["s3:DeleteBucket", "s3:DeleteObject"],
9 "Resource": [
10 "arn:aws:s3:::datalake-empresa",
11 "arn:aws:s3:::datalake-empresa/analytics/*"
12 ]
13 }
14 ]
15}

Deny explícito: ni siquiera un admin puede borrar estos recursos

NUNCA uses "Action": "*" con "Resource": "*" excepto para la cuenta de administrador raíz. Esto da permisos para TODO en toda tu cuenta AWS. Un error con estos permisos puede borrar toda tu infraestructura, exponer datos, o generar facturas de miles de euros. He visto los tres escenarios. No seas esa persona.

### Buenas prácticas de IAM para equipos de datos

  1. 01.Activa MFA (autenticación multifactor) para todos los usuarios humanos, especialmente admins.
  2. 02.Usa roles para servicios, nunca access keys permanentes en código.
  3. 03.Rota las access keys cada 90 días como máximo.
  4. 04.Usa policies gestionadas por AWS como base y personaliza con inline policies.
  5. 05.Revisa permisos no usados con IAM Access Analyzer.
  6. 06.Nunca compartas credenciales entre personas o servicios.
  7. 07.Principio de mínimo privilegio: empieza sin permisos y añade solo lo necesario.

Consejo de senior: cuando debuggees un error de permisos ("Access Denied"), usa el IAM Policy Simulator (disponible en la consola de AWS) para probar qué acciones permite una policy sin ejecutarlas realmente. También puedes activar CloudTrail para ver exactamente qué acción se denegó y por qué policy.

## ejercicios

[01]

Crear role para Glue ETL

El equipo necesita un role para que Glue pueda leer del bucket raw y escribir en processed. Crea el role con la trust policy correcta y los permisos mínimos.

Cargando editor...
[02]

Organizar equipo con grupos IAM

Tu empresa tiene 3 data engineers, 2 analistas y 1 admin. Crea la estructura de grupos con permisos diferenciados: engineers pueden ETL, analysts solo consultan, admin gestiona. Fíjate en lo que le damos a data-admins: exactamente lo que el aviso de arriba prohíbe. Lo hacemos a propósito — es la bomba que vas a desactivar en el ejercicio 3.

Cargando editor...
[03]

Auditar permisos excesivos

Escribe un script que audite todas las policies adjuntas a un grupo y detecte si alguna usa "Action": "*" o "Resource": "*" (permisos demasiado amplios).

Cargando editor...
[04]

Rediseñar policy con mínimo privilegio

El analista Pedro tiene una policy con "s3:*" en todos los buckets. Reescríbela aplicando mínimo privilegio: solo puede leer de analytics/ y ejecutar queries en Athena.

💡 Resultado esperado

{
  "Version": "2012-10-17",
  "Statement": [
    {
Cargando editor...

Regístrate para guardar tu progreso.

## comentarios

Reporta erratas, ayuda a otros o comparte tu opinión. Sé constructivo.

Inicia sesión para comentar y responder.

cargando comentarios...