“Confused Deputy” en integraciones SaaS de terceros: cuando el problema no es tu cuenta, sino el intermediario

El “Confused Deputy” no suele empezar con un exploit sofisticado, sino con una integración “de confianza” que ya tiene llaves para entrar. Conectas un SaaS (monitorización, CI/CD, facturación) y le concedes un rol cross-account o una federación OIDC para que haga trabajo en tu nombre. Si ese tercero no separa bien a sus clientes (tenant isolation) o no valida correctamente el “quién pide qué”, tu cuenta puede acabar ejecutando acciones originadas por otra organización.

En empresa esto suele aparecer como “la culpa no es nuestra”: no hay credenciales comprometidas internas, no hay MFA saltado, no hay un IAM user con permisos excesivos. Sin embargo, hay infraestructura nueva, cambios inesperados o facturación alterada. La pieza que falla está en medio: el deputy (el SaaS) está confundido y actúa para el actor equivocado usando tus permisos.

Qué salió mal en la práctica: el rol de CI/CD que desplegó en la cuenta equivocada

Escenario realista: integras una herramienta de CI/CD de un tercero y creas un rol en tu cuenta cloud con permisos de despliegue (crear/actualizar stacks, registrar imágenes, gestionar buckets de artefactos). La herramienta asume ese rol para ejecutar pipelines. Todo funciona… hasta que un desarrollador de otra empresa (otro cliente del mismo SaaS) lanza un pipeline y, por error de configuración o validación insuficiente del SaaS, ese pipeline termina asumiendo tu rol.

El efecto no siempre es “hackeo” evidente. Puede ser un despliegue con nombres parecidos (mismo repo template, mismo stack name), recursos en regiones que no usáis, o un bucket con artefactos que no pertenecen a vuestro SDLC. En el mejor caso, se detecta por ruido operativo. En el peor, se ejecutan cambios con impacto: rutas en redes, políticas de IAM, rotación de secretos o despliegues que pisan entornos.

Lo importante: el atacante no necesita tus credenciales. Le basta con poder convencer al SaaS (el deputy) para que ejecute una acción en tu cuenta. Si el SaaS no “ata” la solicitud a tu identidad de cliente, tu trust policy se convierte en una puerta demasiado genérica.

La causa raíz: trust demasiado amplio y ausencia de “binding” cliente→rol

El patrón se repite: el rol cross-account confía en la cuenta del proveedor SaaS, y el proveedor opera para múltiples clientes dentro de esa misma cuenta (o un conjunto limitado de cuentas). Si tu trust policy solo dice “confío en la cuenta X del proveedor”, has delegado la separación de clientes a su control interno. Si su control falla, tu aislamiento falla.

En AWS, el “binding” típico se hace con ExternalId (y, dependiendo del caso, condiciones adicionales como aws:PrincipalArn o restricciones de sesión). En federación OIDC (muy común en CI/CD moderno), el binding se hace validando issuer (iss), audience (aud) y claims que identifiquen el repositorio/organización/entorno. Si el proveedor o tu configuración no fijan esos elementos, la identidad que llega al cloud es “válida” pero no “tuya”.

Una señal de diseño inseguro en integraciones SaaS es cuando la documentación sugiere algo equivalente a “cree un rol y confíe en nuestra cuenta” sin condiciones fuertes, o cuando el identificador de cliente no aparece en ninguna parte del flujo de asunción del rol. En corporativo, eso se traduce en un riesgo difícil de explicar… hasta que ocurre.

Señales tempranas y cómo confirmarlo sin especular

El “Confused Deputy” suele dejar trazas operativas que parecen errores humanos: recursos creados por un principal esperado (el rol de integración) pero en momentos extraños, en regiones inusuales o con nombres que no casan con vuestros estándares. Lo peligroso es atribuirlo rápidamente a “alguien se equivocó” y no mirar el origen real de la solicitud.

En AWS, la confirmación se apoya en CloudTrail: identificar eventos de AssumeRole hacia el rol del proveedor, revisar el userIdentity, el principalId, el sourceIPAddress y el sessionContext. Si veis sesiones del rol que no se pueden correlacionar con un pipeline, ticket o ventana de cambio, tratadlo como incidente hasta que se demuestre lo contrario. En integraciones OIDC, revisad los claims usados para la sesión y si el aud corresponde al recurso correcto.

  • Eventos de asunción sin correlación operacional: aparecen sesiones del rol “de CI/CD” pero no hay ejecución de pipeline asociada ni despliegue planificado.

En la práctica, esto fuerza a mejorar la trazabilidad: el rol debería asumir sesiones con nombres o tags que permitan mapear a un job/run concreto. Si el proveedor no lo soporta, es una limitación real que incrementa el coste de investigación.

  • Patrones de recursos “ajenos”: stacks con naming distinto, buckets con políticas estándar de otra organización, o artefactos con rutas que no existen en vuestros repos.

Esto suele indicar que la acción fue “válida” para alguien, pero no para vosotros. No prueba por sí solo el confused deputy, pero es un disparador claro para revisar la trust policy y las condiciones de federación.

Cómo hacerlo en la práctica: guardrails concretos (AWS ExternalId y OIDC con iss/aud)

La mitigación efectiva consiste en reducir la confianza “ciega” en el proveedor y exigir pruebas criptográficas o identificadores que solo correspondan a vuestro alta como cliente. En AWS, el control clásico es ExternalId: el SaaS debe presentar un valor único asignado a vuestro tenant al llamar a STS. Sin ese valor, la asunción debe fallar.

Ejemplo de trust policy en AWS para un rol cross-account, condicionando por ExternalId (ajustad ACCOUNT_ID_SAAS y el external id real):

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::ACCOUNT_ID_SAAS:root" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "YOUR-UNIQUE-EXTERNAL-ID"
}
}
}
]
}

Validación: probad explícitamente que AssumeRole falla sin ExternalId y solo funciona con el valor correcto. Además, revisad periódicamente en CloudTrail que los eventos AssumeRole incluyen ese ExternalId esperado (y que no hay rutas alternativas para asumir el rol).

Para CI/CD moderno con OIDC (por ejemplo, GitHub Actions federando contra Azure/GCP o AWS), el equivalente práctico es validar issuer y audience y restringir por claims de repositorio/organización/entorno. En términos operativos: configurar el IdP/OIDC provider para aceptar únicamente el iss legítimo, exigir un aud específico para vuestra app/recursos, y filtrar por atributos del token (por ejemplo, repo y branch) para que una identidad de otro repo/org no pueda intercambiar su token por permisos en vuestro tenant.

  • Fijar audiencias: el token debe ser emitido para vuestro recurso (audiencia) y no “cualquier cosa válida”.

Esto evita el fallo típico en el que cualquier token OIDC “bien formado” de la plataforma se acepta para asumir permisos. En revisiones internas, este es uno de los hallazgos más comunes cuando se integra rápido y se deja la condición por defecto.

  • Restringir por identidad operacional: el token debe representar exactamente el repo/organización esperados (y, si aplica, el entorno), no solo “un workflow”.

En empresa, esto reduce mucho el blast radius: incluso si alguien obtiene un token válido en su propio contexto, no podrá hacerlo pasar por vuestro contexto. Y cuando ocurra un error de configuración del SaaS, el control fallará cerrado.

Complementos útiles (cuando aporten valor real y no rompan operación) son condiciones por IP de salida del proveedor o por tags de sesión. La clave es no confiar en un único control: ExternalId/OIDC claims para identidad, y restricciones de contexto para reducir abuso.

Operación y limpieza: integraciones que se quedan para siempre (y cómo revocarlas sin parar el negocio)

El “Confused Deputy” empeora con el tiempo por dos motivos: proliferación de integraciones y pérdida de contexto. Roles creados para una prueba de concepto quedan en producción; cuentas de proveedores se renuevan; equipos cambian; y nadie recuerda qué SaaS necesita qué permisos. Ese es el terreno perfecto para Shadow IT con privilegios.

Una práctica que funciona en corporativo es tratar integraciones SaaS como activos con ciclo de vida. No basta con “crear el rol” una vez. Hay que auditar, rotar, reducir permisos y revocar cuando no se usa. Y cuando se revoca, hay que confirmar que no quedan caminos alternativos (otros roles, otros IdPs, llaves antiguas) que mantengan el acceso vivo.

  • Auditoría anual de integraciones SaaS: inventariar cada rol/identidad de terceros, su propietario interno, su justificación y su último uso real observado.

El punto no es hacer un excel para cumplir: es cruzar “último uso” (telemetría) con “necesidad” (proceso de negocio). Muchas integraciones sobreviven por miedo a romper algo, pero cuando se pide evidencia de uso, no existe.

  • Revocación segura: deshabilitar primero por etapas (por ejemplo, reducir permisos o limitar condiciones) y monitorizar fallos antes de eliminar el rol/credencial.

Esto evita caídas silenciosas de procesos críticos. A la vez, fuerza a que el equipo consumidor declare explícitamente la dependencia. Si nadie se queja cuando restringís, era deuda acumulada con privilegios.

Recomendaciones para entornos corporativos

El “Confused Deputy” en integraciones SaaS de terceros aparece cuando delegáis a un proveedor la separación entre clientes, pero vuestro cloud acepta solicitudes solo por “venir de la cuenta del proveedor”. En el día a día, se manifiesta como cambios hechos por un rol esperado, pero sin correlación con vuestra operación.

En la práctica, la defensa pasa por atar cada integración a vuestra identidad de cliente: ExternalId en roles cross-account de AWS y, en flujos OIDC, validar iss y aud y restringir por claims que identifiquen vuestro repo/organización/entorno. Complementad con condiciones contextuales (IP, tags) cuando sean sostenibles y verificables.

Por último, el control que más reduce riesgo a medio plazo es el operativo: auditoría periódica de integraciones y limpieza de roles/identidades de terceros que ya no se usan. En corporativo, lo que no se revisa acaba siendo permanente, y lo permanente acaba siendo el punto de entrada.


¿Te interesa la seguridad en Cloud?

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

Política de privacidad