Arquitectura AWS — Módulo 2: identidad, IAM y el agente como principal
Segundo módulo del curso de arquitectura AWS: todo en AWS es una llamada a una API hecha por una identidad. IAM sin misterio — usuarios vs. roles, políticas, credenciales temporales con STS — y el patrón que gobierna la plataforma: el agente de IA como principal propio, con mínimo privilegio, permisos por tarea y cero llaves de larga vida.
☰ Índice del contenido
El módulo 1 fijó el mapa; ahora, el cimiento. En AWS hay una verdad que simplifica todo lo demás: todo es una llamada a una API — crear una máquina, leer un archivo de S3, invocar un modelo en Bedrock — y toda llamada la firma una identidad con permisos evaluados en ese instante. No existe “acceso a la nube”: existe una identidad concreta pidiendo una acción concreta sobre un recurso concreto, y un motor — IAM (Identity and Access Management) — decidiendo sí o no.
Para una plataforma de agentes esto no es un tema de seguridad que se delega al final: es la pregunta de arquitectura central. Un agente 100% autónomo actúa sin humano que lo frene, así que sus permisos son su jaula — la única. Diseñar la identidad del agente es diseñar exactamente qué puede pasar en el peor caso.
La tesis del módulo
Un agente autónomo en AWS es un principal de IAM: asume un rol, recibe credenciales temporales y puede hacer exactamente lo que su política permite — ni una acción más, sin importar lo que el prompt diga. El mínimo privilegio no es una buena práctica para auditores: es el único límite que un modelo de lenguaje no puede alucinar, negociar ni saltarse. La gobernanza que el prompt sugiere, IAM la garantiza.
Las piezas de IAM, glosadas
- Principal: quien hace la llamada — una persona, un servicio, o tu agente.
- Usuario IAM (user): identidad permanente con credenciales de larga vida (contraseña, access keys). Pensado para humanos — y cada vez menos, porque las llaves de larga vida filtradas son uno de los vectores de incidente más comunes en AWS. La práctica moderna: humanos entran por IAM Identity Center (SSO federado con credenciales que expiran), y las access keys permanentes se consideran deuda.
- Rol (role): identidad sin credenciales propias que un principal asume temporalmente. Al asumirlo, STS (Security Token Service) emite credenciales temporales que expiran solas (minutos a horas). El rol es el mecanismo central de todo lo que corre en AWS: una Lambda, una tarea de ECS o un agente no “tienen contraseña” — asumen su rol de ejecución (execution role) y trabajan con credenciales que caducan.
- Política (policy): documento JSON que declara permisos —
Effect(allow/deny),Action(qué API),Resource(sobre qué),Condition(bajo qué circunstancias). Se adjuntan a principals (¿qué puede hacer esta identidad?) o a recursos (¿quién puede tocar este bucket?). - Trust policy: la política especial de un rol que dice quién puede asumirlo. Es la mitad olvidada: un rol con permisos perfectos pero trust policy laxa es una puerta blindada con la llave puesta.
El flujo completo, que es idéntico para un humano, un microservicio o un agente:
CÓMO ACTÚA UNA IDENTIDAD EN AWS
START ──► ┌───────────┐ ┌───────────────┐
│ principal │ ──► │ asume un rol │
│ (agente) │ │ (STS emite │
└───────────┘ │ cred. temp.) │
└───────┬───────┘
▼
┌───────────────┐
┌── │ llama a la API│
│ │ (firmada) │
│ └───────┬───────┘
│ ▼
│ ┌───────────────┐ deny
│ │ IAM evalúa │ ─────► rechazo
│ │ políticas │ (log)
│ └───────┬───────┘
│ allow ▼
│ ┌───────────────┐
└── │ acción ocurre │ ──► END
siguiente └───────────────┘
llamada
El agente como principal: el patrón de la plataforma
Aquí está la idea que organiza el módulo y que reaparecerá en toda la serie. En la clase de gobernanza del Harness vimos que los permisos efectivos de un agente son la intersección entre lo que el agente puede y lo que el usuario que lo invoca puede — y que la política se declara, no se improvisa. IAM es donde esa teoría se vuelve física en AWS:
- Un rol por agente, no un rol para todos. Cada agente (el clasificador de correos, el cotizador, el reconciliador nocturno) tiene su propio execution role con su propia política. Un “rol de agentes” compartido significa que el agente más inofensivo tiene los permisos del más peligroso.
- Permisos por tarea, no por comodidad. El clasificador de correos necesita: invocar un modelo específico de Bedrock, leer una cola, escribir en una tabla. Su política nombra esas acciones sobre esos recursos — no
bedrock:*, noResource: "*". La diferencia entrebedrock:InvokeModelsobre un modelo ybedrock:*sobre todo es la diferencia entre “el agente clasifica correos” y “el agente puede borrar tus knowledge bases”. - Cero llaves en el código. El anti-patrón letal: una access key en una variable de entorno o — peor — en el prompt o en un archivo que el agente puede leer. Todo lo que corre en AWS obtiene credenciales del rol automáticamente; si tu diseño necesita pegar llaves, el diseño está mal. Y para un agente con herramientas de lectura de archivos, una llave legible es una llave exfiltrable por inyección de prompt.
- Condition como cinturón extra. Las condiciones de política permiten límites que el mundo agéntico agradece: solo desde esta VPC, solo en este horario, solo con este tag. Son el “sí, pero” declarativo.
Ojo — el confused deputy en versión AWS: si tu agente atiende a varios usuarios y usa un único rol potente, un usuario cualquiera puede lograr, vía prompt, que el agente haga cosas que ese usuario no podría hacer solo — el agente actúa como “diputado confundido” con sus permisos amplios al servicio del pedido equivocado. Las soluciones de arquitectura: roles por sesión con permisos reducidos al usuario que invoca (asunción de rol con políticas de sesión), o validación dura en la capa de herramientas. Lo que no funciona: pedirle al prompt que se porte bien.
Ejemplo: la política del clasificador de correos
Así se ve el mínimo privilegio real — la política del agente clasificador del curso (ilustrativa, recortada a lo esencial):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "InvocarSoloSuModelo",
"Effect": "Allow",
"Action": ["bedrock:InvokeModel"],
"Resource": "arn:aws:bedrock:*::foundation-model/anthropic.*"
},
{
"Sid": "LeerSuCola",
"Effect": "Allow",
"Action": ["sqs:ReceiveMessage", "sqs:DeleteMessage"],
"Resource": "arn:aws:sqs:us-east-1:111111111111:correos-entrantes"
},
{
"Sid": "EscribirSuTabla",
"Effect": "Allow",
"Action": ["dynamodb:PutItem"],
"Resource": "arn:aws:dynamodb:us-east-1:111111111111:table/triaje"
}
]
}
Tres statements, tres capacidades, cero comodines de recurso fuera del modelo. Nota lo que esta política no permite: leer otras colas, borrar de la tabla, tocar S3, invocar otros servicios. Si mañana el agente es comprometido por una inyección de prompt brillante, el atacante ganó… la capacidad de clasificar correos. Ese es el objetivo: que el peor caso sea aburrido.
La tabla de decisión de identidades
| Necesitas identidad para… | Usa | Nunca |
|---|---|---|
| Humanos del equipo | Identity Center (SSO, credenciales que expiran) | Usuarios IAM con access keys permanentes |
| Un agente / servicio corriendo en AWS | Rol de ejecución + credenciales temporales | Llaves en variables de entorno |
| CI/CD externo (GitHub Actions) | Federación OIDC → asume rol | Llaves de un usuario IAM en secrets del repo |
| Un agente que llama APIs externas (no-AWS) | Secretos en Secrets Manager, inyectados en runtime (módulo 10) | Llaves en el prompt o en archivos del agente |
| Acceso entre cuentas (dev → prod) | Rol cross-account con trust policy estricta | Compartir credenciales entre cuentas |
Errores comunes
- Un rol Dios para todos los agentes. Compartir rol entre agentes iguala sus radios de explosión al del peor. Rol por agente, política por tarea — es más YAML/JSON, y es exactamente el YAML/JSON que te salva.
Action: "*"“mientras desarrollamos”. El permiso amplio temporal es el más permanente de los artefactos de ingeniería. Nace amplio, nadie lo recorta, y tres años después es el hallazgo crítico de la auditoría.- Descuidar la trust policy. Todo el esfuerzo en la política de permisos y cualquier servicio puede asumir el rol. Las dos mitades — quién puede asumirlo y qué permite — se diseñan juntas.
- Llaves de larga vida en cualquier parte del camino del agente. Variables de entorno, archivos, prompts: si el agente (o su contexto) puede leerla, una inyección puede exfiltrarla. Credenciales temporales de rol o secreto administrado; no hay tercera opción sana.
- Confundir gobernanza de prompt con gobernanza de IAM. “El system prompt le dice que no borre nada” es una sugerencia estadística;
"Effect": "Deny"es una ley física. Las reglas que importan viven en IAM y el prompt solo las repite por cortesía. - Ignorar el confused deputy en agentes multiusuario. Un rol potente al servicio de cualquier usuario que escriba bonito es una escalada de privilegios con interfaz conversacional. Permisos de sesión acotados al invocador, siempre.
La frase para llevarse
“Tu agente puede alucinar respuestas, pero no puede alucinar permisos: hará como máximo lo que su rol permita. Diseña la política del agente como si la inyección de prompt ya hubiera ocurrido — porque el día que ocurra, esa política será lo único que opine.”
Qué viene
Módulo 3: cómputo para agentes. Con identidad resuelta, el agente necesita un lugar donde correr — y AWS ofrece un menú que confunde: Lambda, Fargate, ECS, EKS, Batch. La buena noticia: para agentes de IA, la decisión se reduce a tres preguntas (¿cuánto dura la tarea?, ¿cuánto estado carga?, ¿cuánto tráfico y de qué forma?) y a un mapa de criterios que veremos con los casos del curso. Spoiler: el agente autónomo típico no vive en una API siempre encendida — vive en cómputo que nace cuando hay trabajo y muere cuando termina.
Material relacionado
Preguntas sobre este curso
Regístrate gratis para hacer preguntas y guardar tu progreso.
✉ Entérate de lo nuevo
Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.