Cuando un desarrollador necesita crear un recurso en la nube —una base de datos, un bucket de almacenamiento o una máquina virtual— requiere credenciales para autenticarse con el proveedor. En Google Cloud, esto suele implicar una clave de cuenta de servicio: un archivo JSON que certifica quién es y qué puede hacer.
El inconveniente de estas claves es que son archivos. Se copian, se envían por correo, se suben accidentalmente a repositorios Git, se quedan en portátiles y se olvidan. Cuando alguien abandona un equipo, la organización no siempre sabe qué claves tenía. Rastrear y rotar credenciales entre decenas de desarrolladores se convierte en una carga operativa y un riesgo de seguridad importante.
El término que describe esto es 'dispersión de secretos': credenciales en la nube repartidas por máquinas, canalizaciones y bases de código, difíciles de auditar y aún más de eliminar.
Cómo GitOps eliminó las credenciales
La solución de la comunidad Kubernetes es un operador GitOps (también llamado controlador):
- Un desarrollador escribe archivos de configuración YAML que describen los recursos que necesita, los confirma en Git y los aplica a un clúster de Kubernetes.
- Un controlador que se ejecuta dentro del clúster lee esos archivos y crea o actualiza los recursos en la nube en nombre del desarrollador.
El punto clave: los desarrolladores acaban sin credenciales en la nube. El controlador se autentica en su nombre utilizando las suyas.
La versión de Google de este sistema es Google Kubernetes Config Connector (KCC), que normalmente se ejecuta dentro de un clúster de Google Kubernetes Engine (GKE). KCC observa los archivos de configuración que describen recursos de Google Cloud y llama a la API correspondiente para crearlos o actualizarlos.
Un desarrollador que quiera otorgar a una aplicación permiso para leer objetos de un bucket de almacenamiento podría enviar un recurso IAMPolicyMember. KCC se autentica en Google Cloud mediante Workload Identity, usando una cuenta de servicio de Google controlada por el equipo de plataforma, a menudo llamada KCC GSA. Dado que KCC puede gestionar infraestructura en múltiples proyectos, carpetas o una organización completa, esta cuenta puede recibir roles amplios como role/owner o roles/resourcemanager.organizationAdmin.
Cuando el desarrollador envía el recurso, KCC lo recoge y llama a Google Cloud IAM. El permiso se crea y el desarrollador nunca toca una credencial de Google Cloud.
Esta configuración funciona bien para su propósito: sin credenciales de desarrollador, todo declarado en Git y una sola cuenta de servicio para que el equipo de plataforma controle en lugar de docenas. El problema de la dispersión de credenciales queda resuelto.
Cuando el acceso a un espacio de nombres se convierte en propietario de la organización
Sin embargo, la misma configuración crea un nuevo problema.
KCC realiza todas las operaciones en Google Cloud a través de su propia cuenta de servicio, independientemente de qué usuario de Kubernetes haya enviado el recurso. Si esa cuenta tiene permisos a nivel de organización, un usuario con acceso limitado al clúster puede ejercer esos permisos indirectamente. Esta técnica se denomina ConfigConfusion y fue descubierta por el investigador de seguridad Justin O'Leary.
Si un atacante tiene:
- Acceso a un espacio de nombres de Kubernetes vigilado por KCC.
- Permiso para crear recursos IAMPolicyMember en ese espacio de nombres.
- Ninguna credencial o permiso propio en Google Cloud.
Puede otorgarse a sí mismo cualquier rol de IAM de Google Cloud que la cuenta de servicio de KCC esté autorizada a asignar, incluido roles/owner en toda la organización. El ataque en sí es un solo comando.
El atacante aplica el YAML a través de Kubernetes. KCC lo lee y solicita el cambio de IAM a Google Cloud usando su propia cuenta de servicio, que tiene permiso para hacerlo, por lo que la solicitud se acepta. El atacante ahora controla la organización de Google Cloud sin haber tenido nunca una credencial de Google Cloud.
Dos sistemas de autorización, una verificación ausente
Para entender por qué funciona, hay que examinar los dos sistemas de autorización separados que gestionan la solicitud.
- Kubernetes RBAC controla lo que un usuario puede hacer dentro del clúster. Pregunta: «¿Puede este usuario crear un recurso IAMPolicyMember en este espacio de nombres?» Si la respuesta es sí, permite la operación. No sabe nada de Google Cloud y no pregunta qué hará el recurso allí.
- Google Cloud IAM controla lo que una cuenta de servicio puede hacer en Google Cloud. Cuando KCC llama a Google Cloud para crear la vinculación, pregunta: «¿Tiene la cuenta de servicio de KCC permiso para establecer esta vinculación de IAM?» Si la respuesta es sí, permite la operación. Google Cloud no sabe qué usuario de Kubernetes desencadenó la solicitud y no comprueba si ese usuario debería haber tenido permiso para solicitarla.
Como resultado, Kubernetes solo ve el recurso que se crea dentro del clúster, y Google Cloud solo ve la cuenta de servicio de KCC realizando el cambio. KCC puede recibir una solicitud de un usuario con acceso limitado y ejecutarla usando permisos que ese usuario no tiene en Google Cloud.
Esto se conoce como problema del diputado confundido: KCC tiene una autoridad amplia y actúa según instrucciones de usuarios con menos autoridad, sin comprobar si deberían poder usarla.
La decisión de diseño que elimina las credenciales en la nube de los desarrolladores es útil e intencionada. Pero también elimina el vínculo entre la identidad de Kubernetes de un desarrollador y los permisos de Google Cloud utilizados en su nombre. Cuando KCC actúa, Google Cloud ve a KCC, no a la persona que desencadenó la solicitud.
Google lo considera una característica
La respuesta de Google a ConfigConfusion fue que KCC funciona según lo diseñado. El administrador eligió otorgar a KCC una cuenta de servicio a nivel de organización y permitir que los desarrolladores crearan recursos IAMPolicyMember en espacios de nombres gestionados por KCC. Desde la perspectiva de Google, esas son decisiones de configuración, y KCC lleva a cabo la solicitud que se le dio.
Esa explicación es técnicamente precisa, y KCC hace exactamente lo que está configurado para hacer. El problema es que la documentación no deja clara la relación entre estas dos decisiones. La mayoría de los administradores las consideran por separado: qué tipos de recursos de Kubernetes puede crear este equipo y qué puede hacer la cuenta de servicio de KCC en Google Cloud. En KCC, ambas están conectadas: dar a un equipo permiso para crear un recurso IAMPolicyMember también puede darle una forma de usar la autoridad de KCC en Google Cloud.
Determinar los permisos exactos que necesita KCC es difícil, por lo que otorgar acceso a nivel de organización suele ser más fácil. No refleja necesariamente una mala administración, sino el resultado natural de un diseño que no hace visible la brecha de autoridad resultante.
Por qué es difícil de arreglar
La solución más obvia sería comprobar si el usuario de Kubernetes que envió un recurso tiene el permiso correspondiente en Google Cloud antes de llevar a cabo la solicitud. Esa comprobación depende de que el usuario de Kubernetes tenga una identidad en Google Cloud, pero KCC está diseñado para que no la necesite. Dar a cada usuario una identidad correspondiente socavaría el modelo que KCC fue creado para proporcionar, mientras que buscar los permisos del solicitante para cada recurso añadiría una verificación de autorización y llamadas API adicionales a cada ciclo de reconciliación.
Por lo tanto, las mitigaciones recomendadas por Google se centran en reducir la autoridad disponible a través de KCC, en lugar de cambiar cómo autoriza cada solicitud.
El mismo riesgo en AWS y Azure
El problema de autorización no es exclusivo de KCC. Cualquier operador de infraestructura que acepte instrucciones de una identidad y las ejecute a través de otra puede crear la misma brecha. Lo que cambia entre plataformas es cuánta autoridad tiene el operador y con qué facilidad se puede limitar.
- AWS Controllers for Kubernetes (ACK) separa los controladores por servicio. IAM, Amazon S3 y Amazon EC2 tienen cada uno su propio controlador, con un rol de IAM limitado a ese servicio. Si un usuario obtiene el control de la ruta de solicitud del controlador de S3, puede afectar a los recursos de S3 pero no puede hacer cambios en IAM, porque su rol no tiene esos permisos.
- Azure Service Operator v2 permite que cada espacio de nombres de Kubernetes use una identidad administrada separada. Esto brinda a los administradores una forma práctica de limitar los permisos por espacio de nombres, en lugar de colocar toda la autoridad del operador detrás de una sola identidad.
Ninguno de los dos enfoques elimina el riesgo subyacente de diputado confundido, pero ambos reducen el daño potencial al limitar los permisos del operador antes de que una solicitud maliciosa llegue a él.
Cómo asegurar Config Connector
Para reducir este riesgo, es necesario limitar ambos lados de la brecha de autorización: lo que puede hacer la cuenta de servicio de KCC en Google Cloud y qué usuarios de Kubernetes pueden enviar recursos para que los procese.
La siguiente lista de verificación cubre ambos lados.
- ¿Utiliza KCC el modo con espacio de nombres, con una cuenta de servicio de Google con alcance separado para cada espacio de nombres?
- ¿Ha revisado los roles de IAM de KCC a nivel de proyecto, carpeta y organización?
- ¿Se han eliminado roles amplios como roles/owner y roles/resourcemanager.organizationAdmin a menos que sean estrictamente necesarios?
- ¿Está limitado el permiso para crear recursos IAMPolicyMember, IAMPolicy e IAMPartialPolicy a equipos de plataforma o infraestructura aprobados?
- ¿Supervisa los cambios de IAM a nivel de carpeta y organización realizados por KCC, especialmente los que están fuera del flujo de trabajo GitOps aprobado?
La configuración vulnerable combina una cuenta de servicio de KCC con permisos de IAM a nivel de organización y acceso de escritura amplio a espacios de nombres gestionados por KCC. Cualquiera de las dos condiciones se puede gestionar por separado, pero juntas crean una ruta de escalada de privilegios que no requiere credenciales de Google Cloud para explotarse.
Patrocinado y escrito por Varonis.



















Deja una respuesta