Saltar al contenido
Open Security
Cloud y Producción Intermedio · 30 min

IAM: leer una policy antes de que te muerda

En AWS, los permisos los decide una policy JSON, no tu intuición. Aprendé a leer Effect, Action, Resource y por qué un Deny le gana a cualquier Allow.

#cloud#aws#iam

Antes de empezar necesitás

  • Saber leer JSON
  • Idea básica de IAM (usuarios, roles, policies)

Al terminar vas a poder

  • Leer los cuatro campos clave de una policy: Effect, Action, Resource, Condition
  • Entender por qué un Deny explícito gana sobre cualquier Allow
  • Detectar permisos demasiado amplios (wildcards) en una policy
  • Reescribir una policy peligrosa hacia mínimo privilegio

En la nube no hay un firewall que diga “este pibe puede entrar”. Hay una policy: un JSON que dice, para cada identidad, qué acciones puede hacer sobre qué recursos. Si no sabés leer ese JSON, no sabés qué puede hacer tu cuenta. Y lo que creés que permite casi nunca es lo que permite.

Anatomía de un statement

{
  "Effect": "Allow",
  "Action": ["s3:GetObject", "s3:PutObject"],
  "Resource": "arn:aws:s3:::reportes-prod/*"
}
  • Effect: Allow o Deny.
  • Action: qué llamadas a la API. s3:GetObject es leer un objeto; s3:* es todo S3.
  • Resource: sobre qué. El /* al final acota a los objetos de ese bucket.
  • Condition (opcional): bajo qué circunstancias (una IP, MFA presente, etc.).

La regla que más gente olvida: Deny gana

AWS evalúa así: si algo te niega explícitamente, estás negado, sin importar cuántos Allow tengas. El default ya es negar; un Deny es un cerrojo por encima de todo.

[
  {
    "Effect": "Allow",
    "Action": "s3:*",
    "Resource": "*"
  },
  {
    "Effect": "Deny",
    "Action": "s3:DeleteObject",
    "Resource": "arn:aws:s3:::backups-prod/*"
  }
]

La policy peligrosa

Esta aparece en mil tutoriales y en mil cuentas reales. Leela despacio:

{
  "Effect": "Allow",
  "Action": "*",
  "Resource": "*"
}

Mínimo privilegio: lo que el bot necesita y nada más

Si el laburo del bot es leer reportes de un bucket, su policy es esto y se acabó:

{
  "Effect": "Allow",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::reportes-prod/*"
}

No puede escribir, no puede borrar, no puede tocar otros buckets ni otros servicios. Si esa key se filtra, el daño queda acotado a leer un bucket. Eso es blast radius: cuánto se puede romper cuando algo sale mal.

Probalo sin adivinar

Antes de tocar AWS, leé la policy con el evaluador de abajo: pegás el JSON, elegís una acción y un recurso, y te dice si el resultado es Allow, Deny o el default implícito. Probá con la policy peligrosa y con la de mínimo privilegio.

Evaluador de políticas IAM

Armá una política y probá una acción. AWS evalúa así: un Deny explícito gana siempre; si nada te lo permite, estás denegado por defecto. Los comodines * valen.

¿Se permite ?

Y cuando estés en una cuenta real, AWS tiene un simulador oficial: le pasás una identidad y una acción, y te dice si la policy la permite. Mejor que deducirlo de memoria.

vt@labs:~
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::1234:user/deploy-bot \
  --action-names s3:DeleteObject \
  --resource-arns "arn:aws:s3:::backups-prod/archivo.txt"

Cerrando

Una policy no es burocracia: es el límite real de lo que cada identidad puede hacer. Si sabés leer Effect, Action, Resource y tenés grabado que Deny gana, dejás de confiar en que “alguien la configuró bien” y empezás a verificarlo.

Lo que practicás en este lab

Llevátelo a tu repo si querés, pero no es obligatorio: es tu aprendizaje.

  • Tu análisis de las dos policies de abajo: qué permite cada una de verdad
  • Una policy reescrita de '*' a mínimo privilegio
  • Writeup de 2 líneas: por qué el Deny del ejemplo corta el acceso

Reto

Tomá la policy 'peligrosa' de abajo y reescribila para que un bot solo pueda leer (GetObject) de un único bucket. Mostrá el antes y el después y explicá qué dejaste afuera.

Resolvelo y escribí dos líneas explicando qué pasó. Con eso lo fijás.

¿Hiciste el lab?

Si querés, guardá lo que hiciste (comandos, notas, un repo) para volver después. Y si encontrás un error o querés mejorar este lab, contribuí al repo. El progreso se guarda solo en tu navegador.