Service Accounts en Google Cloud: riesgos reales fuera de los ejemplos oficiales

En Google Cloud, las Service Accounts (SA) son el “usuario” que ejecuta automatizaciones, workloads y pipelines. En la documentación suelen aparecer como un componente limpio y controlado: se crea una cuenta, se le da un rol mínimo, se consume desde un servicio administrado y listo. En empresa, el comportamiento real es distinto: las SA sobreviven años, acumulan permisos por herencia y se autentican con claves que acaban fuera del perímetro esperado.

Este artículo se centra en los riesgos que aparecen cuando entran en juego presión operativa, ownership difuso y cambios de organización. El objetivo es que puedas reconocer señales tempranas y aplicar guardrails que funcionen con equipos y procesos reales.

Superficie de ataque real: cuando las claves largas se convierten en “credenciales permanentes”

El riesgo más repetido fuera del laboratorio es la clave JSON de una Service Account tratada como un secreto más, sin caducidad efectiva y con múltiples copias. Se genera “para desbloquear un despliegue”, se guarda en un gestor de secretos o en un repositorio de CI, y con el tiempo aparece duplicada en varios lugares: entornos de desarrollo, runners self-hosted, backups, e incluso estaciones de trabajo. La clave no expira por sí sola; el riesgo crece con cada copia y con cada sistema que la toca.

En incidentes reales, el vector no suele ser una “intrusión sofisticada” en GCP, sino la exfiltración indirecta: un job de CI con logs verbosos, un bucket con backups accesible por un rol heredado o un repositorio que se hizo público por error. Una vez un atacante obtiene la clave, no necesita pivotar por la consola: puede usar la API desde cualquier lugar, como si fuese el workload legítimo.

  • Copias invisibles en sistemas de build: es común que la clave termine en variables de entorno, artefactos de pipeline o caches. El problema no es solo el secreto, sino el número de sistemas con acceso implícito.

Si tu CI permite descargar artifacts o inspeccionar logs históricos, una clave filtrada no desaparece “al arreglar el pipeline”: hay que asumir compromiso hasta revocarla y auditar uso.

  • Reutilización entre entornos: usar la misma SA/clave para dev, pre y prod es un atajo habitual. El impacto real es que una brecha en dev se convierte en acceso a prod con la misma identidad.

En organizaciones con múltiples equipos, esta reutilización suele justificarse por rapidez. El coste llega después: investigar trazas y atribución se vuelve difícil y el blast radius es innecesariamente amplio.

Rotación que no ocurre: la deuda operativa que se vuelve incidente

La falta de rotación de claves no suele ser una decisión consciente, sino un “no hay tiempo” crónico. Nadie quiere tocar una clave que alimenta procesos críticos si no hay inventario, ni pruebas, ni ventana de mantenimiento. Resultado: claves con años de antigüedad, sin owner claro, desplegadas en sitios que ya nadie recuerda. Cuando hay un hallazgo (por ejemplo, una detección de secreto en un repositorio), la organización descubre que no puede rotar sin romper producción.

En empresa, el síntoma más claro de este riesgo es el miedo a revocar. Si revocar una clave “podría tumbar facturación” o “romper integraciones con terceros”, el problema ya no es técnico: es de gobernanza y de diseño operativo. Además, cuanto más vieja es la clave, más probable es que se haya copiado a sistemas que no están bajo el mismo control (proveedores, consultoras, integraciones legacy).

Cómo hacerlo en la práctica: prepara rotación sin detener el negocio. La secuencia habitual que funciona es doble clave con ventana de coexistencia. Crea una segunda clave, despliega el cambio en consumidores, valida uso, y solo entonces revoca la anterior. En GCP, valida al menos estas piezas antes de borrar:

  • Inventario de consumidores: identifica qué jobs, repos, sistemas de CI/CD, integraciones y VMs usan la clave. Sin esto, rotar es una lotería y se tiende a posponer.
  • Validación por trazas: revisa en Cloud Logging/Audit Logs el principalEmail de la SA y el patrón de llamadas a APIs tras el cambio. La señal de éxito no es “el despliegue pasó”, es ver actividad estable con la nueva clave y ausencia de errores de autenticación.

La clave operativa es tratar la rotación como un cambio de producción: con ventana, rollback (manteniendo la clave antigua un tiempo) y verificación explícita.

Roles heredados y permisos acumulativos: el “crecimiento orgánico” de IAM en Service Accounts

En entornos corporativos, una Service Account rara vez mantiene el rol mínimo inicial. Con el tiempo, equipos distintos van sumando permisos “para resolver un bloqueo”, especialmente cuando no hay ownership claro. El patrón se repite: un pipeline falla por un permiso puntual, alguien añade un rol amplio a nivel de proyecto (o peor, organización), el incidente se resuelve y nadie vuelve a ajustar. Ese rol queda heredado para cualquier uso futuro de la SA, incluso si la SA cambia de propósito.

El problema no es solo el exceso de permisos, sino la combinación de dos cosas: permisos amplios y credenciales exportables (claves). Esa mezcla convierte una SA en un “token maestro” durable. En incidentes, es frecuente encontrar SA con roles como editor/owner en proyectos porque era “más rápido”, o con permisos de administración de IAM que permiten ampliar acceso sin dejar de ser la misma identidad.

Un anti-patrón muy común es delegar en una SA permisos para “gestionar infraestructura” y reutilizarla también para tareas de runtime. Infra y runtime tienen perfiles de riesgo distintos: la primera puede necesitar crear recursos; la segunda debería ser muy restrictiva. Mezclarlas hace que una fuga en runtime tenga impacto de administración.

  • Señal temprana: roles asignados a nivel de proyecto/organización sin justificación por ticket o sin caducidad operativa.

Cuando no puedes explicar por qué una SA tiene un rol, ese rol es deuda y suele ser el primer sitio donde un atacante buscará ampliar impacto.

  • Señal temprana: una SA con permisos de IAM (por ejemplo, capacidad de modificar bindings) usada por pipelines generalistas.

Esto transforma un fallo de autenticación en escalada de privilegios: con una sola identidad, se puede otorgar más acceso a sí misma o a otras identidades si la política lo permite.

Abuso cross-project: cuando una identidad salta entre proyectos sin que nadie lo vea

El abuso entre proyectos aparece cuando una Service Account de un proyecto A obtiene permisos sobre recursos del proyecto B (por bindings directos o por pertenencia a grupos, o por herencia organizacional). En empresas con muchos proyectos, esta práctica se usa para centralizar despliegues o para que un equipo “plataforma” opere recursos de otros. Funciona… hasta que la SA se compromete o se reutiliza fuera de su contexto original.

El impacto real suele manifestarse como movimiento lateral: una SA que nació para un pipeline de un microservicio termina leyendo secretos en otro proyecto, escribiendo en buckets compartidos o administrando recursos de red. En un incidente, esto complica el containment: revocar en el proyecto A no siempre corta el acceso a B si el acceso estaba concedido de forma cruzada o por herencia. Además, la atribución se diluye: muchas operaciones en B aparecen como “la SA del pipeline”, sin claridad de qué equipo la ejecutó realmente.

Cómo hacerlo en la práctica: revisa y corta saltos innecesarios entre proyectos. Acciones concretas que suelen dar resultados rápidos:

  • Mapear bindings cross-project: enumera dónde aparece el principal (serviceAccount:…) de una SA fuera de su proyecto. El hallazgo típico es “no sabíamos que esta SA tenía acceso a ese proyecto”.

En cuanto lo encuentres, fuerza conversaciones de ownership: si no hay owner del acceso en el proyecto destino, es un permiso huérfano y debe eliminarse o reemplazarse por un mecanismo más controlado.

  • Separar identidades por dominio: crea SA distintas por proyecto y por función (deploy vs runtime). Si necesitas operar cross-project, que sea una SA diseñada para ello y con permisos acotados y auditables.

La separación reduce blast radius y mejora investigación: en logs, una identidad específica cuenta una historia mucho más precisa que una SA “multiuso”.

Recomendaciones para entornos corporativos

Los riesgos más dañinos con Service Accounts en Google Cloud aparecen cuando se combinan claves largas con baja rotación, roles que crecen por herencia y accesos cross-project concedidos por conveniencia. No fallan por desconocimiento técnico, sino por presión operativa y falta de ownership: se prioriza “que funcione hoy” y se difiere indefinidamente el control.

Si tienes que elegir dónde empezar, prioriza lo que reduce impacto de forma inmediata: inventariar y rotar claves con coexistencia controlada, recortar roles heredados que nadie puede justificar y mapear accesos cross-project para eliminar permisos huérfanos. Con estas tres líneas, los incidentes típicos pasan de “compromiso amplio y difícil de contener” a “evento acotado y trazable”.


¿Te interesa la seguridad en Cloud?

Comparto análisis técnicos, laboratorios prácticos y experiencias reales sobre Cloud Security.

Política de privacidad