AWS Certified CloudOps Engineer - Associate

Políticas y roles de IAM

Las piezas con las que se toma cada decisión de autorización en AWS: principals e identidades, los elementos de una política JSON, políticas de identidad contra políticas de recurso, managed contra inline, y por qué un rol lleva dos políticas en vez de una.

Intermedio 26 minutos 7 Objetivos de aprendizaje
  1. Distinguir un principal de una identidad y nombrar los tipos de política que AWS asocia a cada uno
  2. Leer una política JSON elemento por elemento y predecir qué permite
  3. Elegir entre una política de identidad y una política de recurso según el requisito de acceso
  4. Explicar por qué un rol de IAM lleva una trust policy y una permissions policy, y qué solicitud controla cada una
  5. Pasar un rol a una instancia EC2 con un instance profile y describir cómo recibe las credenciales la aplicación
  6. Comparar las operaciones de AWS STS que emiten credenciales temporales por llamador, duración y soporte de MFA
  7. Enunciar qué cambia en la evaluación de políticas cuando la solicitud cruza el límite de una cuenta

Tu aplicación corre en 40 instancias EC2 y necesita leer de un bucket de S3. La respuesta directa es crear un usuario de IAM, generar una access key y dejarla en un archivo de configuración de la instancia. Funciona en la primera. Después la key queda horneada en la AMI, la AMI se comparte, alguien pega la key en un ticket de soporte, y la rotación que agendaste para el trimestre siguiente ahora significa tocar 40 máquinas a la vez. Esa key no vence nunca, y nada dentro de AWS te va a avisar que se escapó.

Casi todo este dominio existe para que ese patrón no haga falta. Esta lección arma el vocabulario que el resto del dominio da por sabido: de qué está hecha una política, qué tipos de política adjunta AWS y dónde, y por qué un rol es la respuesta al problema de las access keys y no un envoltorio un poco más lindo alrededor de ellas.

Principals, identidades y qué es realmente una política

Un principal es quien hace una solicitud. Puede ser el usuario root de la cuenta, un usuario de IAM, una sesión de rol o un servicio de AWS actuando por ti. Una identidad es el objeto de IAM del que sale ese principal: un usuario, un grupo o un rol.

Una política es un documento JSON que, una vez adjunto a una identidad o a un recurso, define permisos. Cuando un principal manda una solicitud, AWS junta todas las políticas que aplican y decide allow o deny. El default importa: toda solicitud se rechaza salvo que alguna política la permita, con la única excepción del usuario root, que tiene acceso completo.

AWS soporta 9 tipos de política. Vas a conocerlos todos a lo largo del dominio, y para esta lección te alcanzan 3:

Tipo de políticaSe adjunta a¿Otorga permisos?
De identidadUsuario, grupo o rol
De recursoUn recurso (bucket, cola, key, rol)
Permissions boundaryUn usuario o un rolNo, pone un techo
SCP y RCP (Organizations)Raíz, OU o cuentaNo, ponen un techo
De sesiónSe pasa al crear la sesiónNo, pone un techo
De VPC endpointUn VPC endpointNo, acota el tráfico que pasa por el endpoint
ACLUn recurso, con sintaxis que no es JSONSí, solo entre cuentas
Resource share de AWS RAMUn recurso compartido

Mira la tercera columna. Solo 3 de estos tipos reparten permisos de verdad. El resto pone techos, y por eso "la política lo permite" y "la solicitud funciona" son afirmaciones distintas. La próxima lección trata enteramente de esa diferencia.

La anatomía de una política JSON

Toda política JSON tiene información opcional arriba y uno o más statements. AWS aplica un OR lógico entre los statements de una política y entre todas las políticas que aplican, así que un solo allow alcanza (salvo que algo deniegue).

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadReportsBucket",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::finance-reports",
        "arn:aws:s3:::finance-reports/*"
      ],
      "Condition": {
        "Bool": { "aws:SecureTransport": "true" }
      }
    }
  ]
}

Los elementos, y la trampa que trae cada uno:

  • Version es la versión del lenguaje de políticas, no una versión de tu política. Usa 2012-10-17. Un valor viejo o ausente desactiva en silencio las variables de política.
  • Sid es una etiqueta opcional. No afecta la evaluación, pero es lo que ves cuando estás cazando el statement que rechazó algo, así que ponle nombre.
  • Effect es Allow o Deny.
  • Principal nombra a quién aplica la política. Es obligatorio en una política de recurso y está prohibido en una política de identidad, donde el principal queda implícito por aquello a lo que la política está adjunta. Ver un bloque Principal te dice al instante qué tipo de política estás leyendo.
  • Action lista acciones de servicio en forma servicio:Operacion, y admite *.
  • Resource lista ARNs. El bucket y los objetos que contiene son 2 ARNs distintos, y por eso el ejemplo de arriba lista los dos. Una política que solo tenga arn:aws:s3:::finance-reports permite listar pero no leer un objeto.
  • Condition hace que el statement aplique solo cuando la condición es verdadera. Las condiciones son el tema de la próxima lección.

Una regla que conviene interiorizar ya: un statement cuya condición no se cumple simplemente no aplica. No deniega; se cae de la evaluación y deja la solicitud en manos de lo que sea que la permita, que normalmente es nada.

Políticas de identidad contra políticas de recurso

Las dos otorgan permisos. Se diferencian en qué pregunta responden.

Una política de identidad responde "¿qué puede hacer esta identidad?" y vive en el usuario, el grupo o el rol. Una política de recurso responde "¿quién puede tocar este recurso?" y vive en el recurso: una bucket policy de S3, una queue policy de SQS, una key policy de KMS, una function policy de Lambda, la trust policy de un rol de IAM.

De identidadDe recurso
Se adjunta aUsuario, grupo, rolEl recurso mismo
Elemento PrincipalNo se permiteObligatorio
Managed o inlineLas dosSolo inline, no existen políticas de recurso managed
Entre cuentasNombra el recurso en la otra cuentaNombra el principal de la otra cuenta

Dentro de una misma cuenta las dos se unen: un allow en cualquiera alcanza, y un deny explícito en cualquiera gana. Por eso Zhang, sin ninguna política de identidad, igual puede leer una cola cuya queue policy lo nombra.

Hay dos excepciones que vale la pena memorizar porque al examen le gustan. Las trust policies de roles de IAM y las key policies de KMS tienen que permitir al principal de forma explícita. El atajo de la unión no te salva ahí: una política de identidad que otorga kms:Decrypt sobre una key cuya key policy nunca te menciona no alcanza.

Managed contra inline

Las políticas de identidad vienen en 2 formas, y la elección trata de reutilización y ciclo de vida, no de poder.

Las managed policies son objetos independientes que adjuntas a muchas identidades. Las AWS managed policies las escribe y mantiene AWS (AmazonS3ReadOnlyAccess, AdministratorAccess, y las políticas por función laboral). Las customer managed policies son tuyas. Editas una y todos los adjuntos cambian a la vez.

Las políticas inline van incrustadas directamente en un solo usuario, grupo o rol. Tienen una relación estricta de uno a uno con esa identidad y se borran cuando la identidad se borra.

La guía de AWS es arrancar con AWS managed policies para tener una base que funcione, y después acotar hacia customer managed policies a medida que descubres qué permisos usa realmente la carga de trabajo. Las AWS managed policies están escritas para servirle a cualquier cliente de AWS, que es exactamente la razón por la que casi nunca son mínimo privilegio para el tuyo.

Usa inline cuando el permiso no deba sobrevivir a la identidad, o cuando quieras garantizar que nadie lo adjunte por accidente en otro lado.

Roles: dos políticas, dos preguntas

Acá está el concepto que sostiene el resto del dominio. Un rol es una identidad con permisos, como un usuario, pero con 2 diferencias que lo cambian todo:

  1. No está atado a una persona. Cualquiera que el rol permita puede asumirlo.
  2. No tiene credenciales de larga vida. Ni contraseña ni access key. Asumir un rol produce credenciales temporales que vencen.

Ese segundo punto es lo que resuelve el problema del inicio. Nada que hornear en una AMI, nada que rotar, nada que se filtre para siempre.

Para lograrlo, un rol lleva 2 políticas que controlan 2 solicitudes distintas:

  • La trust policy es una política de recurso sobre el rol. Responde quién puede convertirse en este rol. Es lo único que se consulta cuando alguien llama a sts:AssumeRole. En el elemento Principal de una trust policy no se permiten comodines dentro de un ARN.
  • La permissions policy es una política de identidad sobre el rol. Responde qué puede hacer la sesión resultante. Nunca se consulta durante la llamada de assume-role.

Una trust policy mínima para una carga de trabajo en EC2:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Service": "ec2.amazonaws.com" },
      "Action": "sts:AssumeRole"
    }
  ]
}

Y para una persona de otra cuenta:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "AWS": "arn:aws:iam::111122223333:root" },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": { "sts:ExternalId": "a1b2c3d4-audit-2026" }
      }
    }
  ]
}

La condición sts:ExternalId es la defensa estándar contra el problema del confused deputy. Cuando le das un rol en tu cuenta a un tercero (una auditoría, un proveedor de monitoreo), ese tercero tiene roles de muchos clientes. Sin external ID, un cliente que averigüe el ARN de tu rol podría pedirle al proveedor que lo asuma en su nombre. El external ID es un secreto que comparten tú y el proveedor, y vuelve la trust policy específica de esa relación en vez de específica del proveedor entero.

Este es además el corte diagnóstico más útil de todo IAM. Las 2 compuertas fallan con mensajes distintos. not authorized to perform: sts:AssumeRole apunta a la trust policy. not authorized to perform: s3:GetObject apunta a la permissions policy. La última lección del tema convierte esa observación en un procedimiento completo.

Cómo llega un rol a una instancia EC2: el instance profile

Un rol es un objeto de IAM. EC2 necesita un contenedor donde adjuntarlo, y ese contenedor es un instance profile.

La regla que produce preguntas de examen: un instance profile puede contener 1 solo rol de IAM, y ese límite no se sube. Un rol sí puede aparecer en muchos instance profiles, pero nunca al revés.

La confusión arranca porque la consola esconde el objeto. Crea un rol para EC2 en la consola y te crea un instance profile con el mismo nombre, sola. Crea el mismo rol desde la CLI o la API y obtienes un rol y nada más, así que el asistente de lanzamiento (que lista nombres de instance profile, no de rol) no te muestra nada.

# desde la CLI, esto son 3 pasos separados
aws iam create-role \
  --role-name AppServerRole \
  --assume-role-policy-document file://trust-policy.json

aws iam create-instance-profile --instance-profile-name AppServerProfile

aws iam add-role-to-instance-profile \
  --instance-profile-name AppServerProfile \
  --role-name AppServerRole

# adjuntar a una instancia en ejecución
aws ec2 associate-iam-instance-profile \
  --instance-id i-02573cafcfEXAMPLE \
  --iam-instance-profile Name=AppServerProfile

Una vez adjunto, los SDK de AWS de la instancia encuentran las credenciales por el servicio de metadata sin ninguna configuración, y el servicio las rota antes de que venzan. Para cambiar lo que puede hacer una instancia, reemplaza el instance profile en vez de cambiar el rol de adentro: sacar un rol de un instance profile puede tardar hasta una hora en tener efecto, porque el cambio tiene que propagarse.

Service roles y service-linked roles

Dos variantes de rol que el examen nombra con precisión.

Un service role es un rol que un servicio de AWS asume para actuar por ti. Lo creas tú, escribes su trust policy nombrando al service principal, y puedes editar sus permisos. El rol de build de CodeBuild y el rol de EC2 de arriba son service roles.

Un service-linked role lo crea y lo posee el servicio. Aparece en tu cuenta, sus permisos los define el servicio, y desde administración se pueden ver pero no editar. Tampoco lo puedes borrar hasta borrar los recursos que dependen de él, lo que te protege de dejar huérfanos recursos que el servicio ya no puede administrar.

Si una pregunta te entrega un rol que no creaste y te pregunta por qué no se puede acotar su política, es un service-linked role.

Conseguir credenciales temporales: las operaciones de STS

AWS Security Token Service emite cada credencial temporal de AWS. Las 5 operaciones se diferencian por quién puede llamarlas y cuánto vive el resultado.

OperaciónQuién puede llamarlaDuración (mín, máx, default)Acepta MFAPolítica de sesión
AssumeRoleUsuario de IAM o un rol con credenciales temporales vigentes15 min, duración máxima del rol, 1 h
AssumeRoleWithSAMLCualquiera con una respuesta SAML de un IdP conocido15 min, duración máxima del rol, 1 hNo
AssumeRoleWithWebIdentityCualquiera con un JWT de OIDC de un IdP conocido15 min, duración máxima del rol, 1 hNo
GetFederationTokenUsuario de IAM o usuario rootUsuario IAM: 15 min, 36 h, 12 h. Root: 15 min, 1 h, 1 hNo
GetSessionTokenUsuario de IAM o usuario rootUsuario IAM: 15 min, 36 h, 12 h. Root: 15 min, 1 h, 1 hNo

Tres detalles deciden preguntas acá.

La duración máxima de sesión configurada en el rol es el techo de cada variante de assume-role, y se puede subir hasta 12 horas. Pide más de lo que el rol permite y la llamada falla en vez de devolverte una sesión más corta.

Solo AssumeRole y GetSessionToken aceptan información de MFA. Eso es lo que hace verdadera a aws:MultiFactorAuthPresent para la sesión resultante, que es la clave con la que la próxima lección exige MFA en acciones sensibles.

GetSessionToken no te puede firmar en la consola por el endpoint de federación, y GetFederationToken sí. Si un escenario pide single sign-on a la consola desde un broker de identidad propio, la operación es GetFederationToken.

Role chaining y duración de sesión

El role chaining es usar las credenciales de un rol para asumir un segundo rol. Es común en pipelines y en herramientas entre cuentas, y trae un límite duro: una sesión encadenada se limita a 1 hora, sin importar la duración máxima configurada en el rol destino. Pasar un DurationSeconds mayor a 3600 en una llamada encadenada hace que la operación falle.

Es tentador leer eso como "la sesión se recorta a una hora". No pasa eso. La llamada devuelve error, y por eso un pipeline que funcionaba con una sesión de 4 horas desde las credenciales de un usuario se rompe el día que alguien mete un rol intermedio.

Acceso entre cuentas: la regla que cambia

Dentro de una cuenta, las políticas de identidad y de recurso se unen. Entre cuentas, los dos lados tienen que permitir la solicitud. La cuenta del principal tiene que otorgar un allow de identidad para la acción sobre el recurso destino, y la cuenta del recurso tiene que nombrar a ese principal en una política de recurso o en una trust policy. Un solo lado siempre falla.

Esa asimetría explica la mayoría de los tickets entre cuentas. Una bucket policy que generosamente permite a arn:aws:iam::111122223333:root no hace nada hasta que alguien de administración en la cuenta 111122223333 le otorgue además a alguna identidad el s3:GetObject correspondiente. Nombrar el root de una cuenta en una bucket policy delega en esa cuenta; no otorga a cada principal de adentro.

Consejos para el examen

  • Si la política tiene Principal, es una política de recurso. Si no lo tiene, es de identidad. Ese elemento identifica el tipo más rápido que leer todo lo demás.
  • "Una aplicación en EC2 necesita llamar a un servicio de AWS" siempre significa instance profile con un rol, nunca una access key en la instancia.
  • 1 rol por instance profile, y un rol puede vivir en muchos instance profiles. Sacar un rol de un instance profile tarda hasta 1 hora, así que en un escenario la solución es reemplazar el instance profile.
  • Dos mensajes de error, dos políticas: sts:AssumeRole denegado es la trust policy, la acción destino denegada es la permissions policy.
  • El role chaining se limita a 1 hora y falla en vez de recortar.
  • Las palabras "tercero", "proveedor" o "auditoría" en un escenario de rol entre cuentas apuntan a sts:ExternalId y al confused deputy.
  • Entre cuentas hacen falta allows en los dos lados. En la misma cuenta alcanza con uno, salvo trust policies de roles y key policies de KMS, que tienen que nombrar al principal.
  • Un rol cuyos permisos no puedes editar es un service-linked role.

La regla que te llevas de esta lección: en AWS las credenciales deberían tener vencimiento, y la forma de conseguir un vencimiento es un rol. Todo lo demás de acá es contabilidad alrededor de esa única idea. La próxima lección toma las políticas que ya sabes leer y responde la pregunta difícil: qué pasa cuando 5 de ellas aplican a la misma solicitud y no se ponen de acuerdo.