El patrón se repite: una vulnerabilidad en una API dentro de un contenedor (RCE, SSRF, deserialización insegura) parece “solo” un incidente de aplicación. Pero en EKS/AKS modernos, el Pod suele tener una identidad cloud (IRSA en AWS, Workload Identity en Azure) para acceder a recursos. Si esa identidad está sobredimensionada o mal acotada, el atacante no necesita romper el plano de control de Kubernetes: le basta con usar credenciales válidas y escalar en la nube subyacente hasta niveles equivalentes a “root” (por ejemplo, control total del tenant o de la cuenta).
Lo crítico no es la existencia de IRSA/Workload Identity, sino el modelo de permisos y el aislamiento: qué puede asumir ese Pod, qué recursos puede tocar, qué puede crear/modificar y qué “puertas de escalada” existen (políticas IAM amplias, roles con capacidad de delegación, identidades con permisos sobre RBAC, etc.).
Qué salió mal: cuando la identidad del Pod se convierte en llave maestra
En AWS, un Pod con IRSA obtiene credenciales temporales de un rol IAM. En Azure, un Pod con Workload Identity (federación OIDC) obtiene tokens para una identidad (Managed Identity o App Registration/Service Principal). En ambos casos, el diseño pretende eliminar secretos estáticos. El problema aparece cuando a esa identidad se le otorgan permisos “de plataforma” por conveniencia: administrar IAM/Entra ID, crear roles, modificar políticas, operar redes, o gestionar clústeres.
En incidentes reales, el punto de partida suele ser mundano: una imagen de contenedor con un servidor expuesto, una librería vulnerable o un endpoint que permite SSRF hacia metadata. El atacante no necesita persistencia sofisticada; con ejecutar unas llamadas a AWS STS o al endpoint de token de Azure desde el Pod, ya tiene una identidad cloud operativa para pivotar.
La consecuencia empresarial más común es que el incidente deja de ser “una app caída” y pasa a ser un evento de seguridad cloud: creación de usuarios/roles, exfiltración de datos en buckets/cuentas de storage, modificación de reglas de red para mantener acceso, y despliegue de cargas para minería o backdoors. En entornos con automatización amplia (CI/CD con privilegios, IaC con permisos extensos), la escalada puede ser cuestión de minutos.
Cadena de ataque típica: de RCE/SSRF en el contenedor a control del tenant
La cadena no suele requerir explotar Kubernetes como tal. El atacante compromete un Pod, obtiene su identidad cloud y ejecuta acciones en la API de AWS/Azure. En AWS, el objetivo frecuente es encontrar un rol con permisos para crear/modificar políticas o para asumirse a sí mismo roles más privilegiados. En Azure, el objetivo suele ser obtener permisos sobre subscriptions/resource groups, o sobre Entra ID (roles de directorio) para persistir y escalar.
Un ejemplo común en AWS: el rol de IRSA tiene permisos para administrar IAM “porque el equipo de plataforma necesitaba que un controlador funcionara”. Con eso, el atacante puede adjuntar una política administrada amplia o crear una nueva política y adjuntarla al rol actual, o crear un rol nuevo con trust policy abierta y asumirlo. En Azure, una Managed Identity con Contributor a nivel de subscription puede crear recursos con identidades, asignar roles (si además tiene permisos de RBAC), o modificar infraestructura para abrir caminos de salida.
- Permisos de escritura sobre identidad: permitir
iam:CreatePolicy,iam:AttachRolePolicyo equivalentes en Azure (roleAssignments write) suele convertir la identidad del Pod en un “escalador” directo.
En empresa, esto se traduce en que una vulnerabilidad en una app interna (por ejemplo, un microservicio de facturación) termina permitiendo modificar la política de un rol compartido por múltiples servicios, amplificando el impacto. El equipo ve actividad “legítima” en CloudTrail/Activity Logs porque, técnicamente, lo es: proviene de una identidad válida.
- Capacidad de creación de infraestructura con privilegios: si el Pod puede crear instancias/VMs, funciones o recursos con roles/identidades anexas, puede fabricar un punto de ejecución más “cómodo” con permisos mayores y persistencia fuera del clúster.
El patrón operativo detrás de estos incidentes es la falta de separación entre identidades de “workload” (microservicios) y capacidades de “plataforma” (IAM/RBAC, redes, clústeres). Cuando se mezcla, el Pod se convierte en un punto de entrada a la cuenta.
Señales tempranas que delatan escalada desde un Pod (antes de que sea tarde)
La detección no debería depender solo de alertas de “container breakout”. Aquí el atacante opera por APIs de cloud con credenciales temporales. En AWS, CloudTrail muestra AssumeRoleWithWebIdentity y luego una secuencia de llamadas inusuales para ese rol. En Azure, los Activity Logs y Entra ID sign-in logs reflejan accesos federados y asignaciones de rol o cambios de recursos fuera del patrón normal del workload.
En entornos corporativos, una señal fuerte es la divergencia entre el comportamiento esperado del Pod (leer de S3/Storage, consultar una cola) y la actividad real (crear políticas, listar secretos, describir VPC/VNet, crear role assignments). Otro indicador útil: aumentos de permisos (policy attachments, role assignments) en horarios o desde regiones no habituales, o desde identidades asociadas a namespaces “de aplicación” en vez de “plataforma”.
- AWS: ráfagas de
iam:*osts:AssumeRoledesde un rol de IRSA, especialmente si el rol históricamente solo usabas3:GetObjectosecretsmanager:GetSecretValue.
En operación diaria, esto se valida correlacionando CloudTrail con el nombre del rol usado por IRSA y el namespace/serviceAccount correspondiente. Si la identidad del Pod ejecuta acciones fuera del conjunto aprobado para ese servicio, no es “ruido”: suele ser el inicio (o la continuación) de una escalada.
- Azure: creación/modificación de
roleAssignments, cambios deMicrosoft.Authorization/*o acciones administrativas desde una Workload Identity asociada a un microservicio.
Una dificultad real es cultural: muchos equipos aceptan permisos amplios “temporalmente” para desbloquear despliegues. Esa temporalidad rara vez se revierte, y la detección se complica porque las acciones pasan controles estándar de autenticación y autorización.
Cómo hacerlo en la práctica: hardening de IRSA (AWS) y Workload Identity (Azure) para cortar la escalada
El objetivo práctico es que un Pod comprometido tenga un “radio de explosión” pequeño: permisos mínimos, sin capacidad de delegación, sin administración de identidades, y con condiciones que amarren la federación al service account exacto. Esto se consigue combinando políticas IAM/RBAC bien acotadas, límites de permisos y controles de asignación de identidad por namespace.
AWS (EKS + IRSA): empieza por blindar la trust policy del rol y luego recortar su policy de permisos. La trust policy debe limitar por sub (serviceAccount) y aud, evitando comodines por namespace. Un ejemplo de trust policy correcta (ajusta tu OIDC provider y namespace):
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:aud": "sts.amazonaws.com",
"oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:sub": "system:serviceaccount:payments:svc-payments-api"
}
}
}]
}
Después, valida que el rol no pueda escalar por IAM. En la práctica, eso implica: eliminar cualquier iam:* que no sea estrictamente necesario; evitar permisos de escritura sobre políticas/roles; y, si tu organización lo soporta, aplicar un permissions boundary que impida adjuntar privilegios administrativos incluso si alguien logra introducir un permiso nuevo por error.
Validación en AWS: revisa en IAM el rol asociado al service account y verifica (1) trust policy sin comodines por namespace, (2) políticas adjuntas sin acciones de IAM/STS peligrosas, (3) CloudTrail para confirmar que el rol solo llama a servicios esperados. Un chequeo concreto y repetible es buscar eventos de AttachRolePolicy, PutRolePolicy, CreatePolicyVersion o AssumeRole emitidos por ese rol: si aparecen, el diseño está permitiendo delegación o escalada.
Azure (AKS + Workload Identity): el control clave es que la federación OIDC esté restringida al subject del service account y que la identidad tenga roles mínimos en el scope más pequeño posible (resource group o recurso, no subscription). En la práctica corporativa, donde más se rompe esto es al asignar Contributor a nivel de subscription para “acelerar”. Eso habilita movimientos laterales por infraestructura y, si además existen permisos para role assignments, la escalada es directa.
Validación en Azure: confirma que la identidad usada por el workload no tenga roles amplios en scopes altos (subscription/management group) y revisa Activity Logs por operaciones de autorización (Microsoft.Authorization/roleAssignments/write) originadas por esa identidad. Si aparecen, el workload está en una zona peligrosa: incluso un SSRF puede desencadenar cambios de permisos.
Errores típicos que abren la puerta a “root” sin tocar Kubernetes
El error más caro es tratar identidades de workloads como identidades de plataforma. En AWS, asignar a un rol de IRSA permisos pensados para operadores (IAM, organizaciones, redes) porque “lo necesita el controlador” suele ser una decisión táctica que se vuelve estructural. En Azure, el equivalente es usar Managed Identities de aplicación con Contributor/Owner para evitar fricción con deployments y luego reutilizarlas en varios namespaces.
Otro fallo repetido es la reutilización de identidades: un mismo rol/identidad para múltiples service accounts o namespaces. Eso convierte un compromiso en un microservicio en compromiso de “todo lo que comparte identidad”. En incidentes internos, este diseño complica la respuesta: revocar el rol corta producción de varias apps, así que se pospone la contención, y el atacante gana tiempo.
- Comodines en trust/federation: permitir asumir el rol desde cualquier
system:serviceaccount:*o no fijar el subject en Azure facilita que cualquier Pod que consiga crear/usar un service account “apunte” a esa identidad.
En empresa, esto suele aparecer tras migraciones rápidas: se copia una configuración “que funciona” y se generaliza. El resultado es que el aislamiento por namespace es más cosmético que real.
- Permisos para leer secretos + egress libre: si el Pod puede leer Secret Manager/Key Vault sin límites y además tiene salida a Internet sin control, la exfiltración es trivial y difícil de distinguir de tráfico normal.
Esto no es teoría: muchos equipos descubren el problema al auditar después de un pentest. El hallazgo típico no es “escape del contenedor”, sino “la identidad del Pod puede listar secretos de otros sistemas y modificar permisos”.
Recomendaciones para entornos corporativos
El riesgo de pasar de un Pod comprometido a control total de la nube no depende de “hackear Kubernetes”, sino de cómo se han modelado identidades y permisos alrededor de IRSA/Workload Identity. Si la identidad del workload puede delegar, administrar IAM/RBAC o crear infraestructura con privilegios, la escalada es una consecuencia operativa, no una sorpresa.
En la práctica corporativa, la reducción de riesgo pasa por: amarrar estrictamente la federación al service account correcto, eliminar permisos de plataforma de identidades de aplicación, evitar reutilización de roles/identidades entre workloads, y validar continuamente con trazas (CloudTrail/Activity Logs) que los roles de Pod solo ejecutan acciones esperadas. Cuando esto se hace bien, una vulnerabilidad en un microservicio se queda en su perímetro y deja de ser un puente hacia “root” en la cuenta.
¿Te interesa la seguridad en Cloud?
Comparto análisis técnicos, laboratorios prácticos y experiencias reales sobre Cloud Security.