Patrones y controles de arquitectura para impedir que el cliente o un MCP malicioso se apropien de la identidad del usuario
Si el token toca el prompt, date por muerto.
En este artículo revisamos cómo desplegar MCP en producción evitando la suplantación de identidad. Se resumen los principales riesgos (confused-deputy, tool poisoning, supply chain) y se presentan patrones de autenticación y autorización seguros: DPoP, mTLS, token exchange, phantom tokens y firmas HTTP. Todo bajo un principio común: el token nunca debe tocar el prompt.
Contexto
MCP estandariza la forma en que un host o cliente (IDE, chat, agente) descubre y utiliza herramientas y recursos expuestos por servidores externos. El beneficio en interoperabilidad y dinamismo es evidente, pero también lo es el incremento de la superficie de ataque: credenciales, contexto del usuario y acciones privilegiadas pasan a orquestarse por un agente que razona en lenguaje natural.
El objetivo de esta guía es describir un modelo de amenazas focalizado en suplantación de identidad y exfiltración de credenciales, y proponer patrones de autenticación y autorización que no dependan de la corrección del modelo ni del buen comportamiento de terceros.
Principio de diseño
Separar semántica de seguridad.
El modelo decide qué hacer; la plataforma decide con qué identidad, bajo qué permisos y a través de qué controles. El material de autenticación no debe estar disponible para el modelo ni viajar dentro de los prompts o descripciones de herramientas.
Modelo de amenazas (resumen)
Amenaza | Descripción | Impacto | Medidas de arquitectura |
---|---|---|---|
Confused deputy en MCP | El servidor actúa como proxy y acepta o reenvía tokens ajenos | Suplantación del usuario hacia downstream | Validar audiencia y resource; prohibir passthrough; token exchange con scopes mínimos |
Secuestro de sesión | Reutilización de session IDs entre instancias o colas | Impersonación sin romper criptografía | No usar sesión como autenticación; ligar sesión a identidad; expiración y rotación |
Tool/prompt poisoning | Metadatos o prompts que inducen acciones indebidas | Exfiltración de datos; ejecución indirecta | Revisión y firma de servidores; allow‑list; aislamiento por contenedor y egress controlado |
Supply chain (typosquatting) | Instalación de servidores MCP con nombres plausibles | Código arbitrario en el entorno del agente | Registros verificados; paquetes firmados; SBOM; negar auto‑instalaciones sugeridas por el modelo |
Exfiltración de conversación | Herramienta que induce a enviar historial | Pérdida de confidencialidad | Políticas de datos; segmentación de contexto; controles de egreso |
Patrones de autenticación y autorización
1) Sender‑constrained tokens: DPoP o mTLS
Objetivo: que robar el token no sirva para reutilizarlo fuera de su canal legítimo.
- DPoP (Proof‑of‑Possession): el token queda ligado a una clave pública del cliente. Cada petición incluye una prueba firmada con esa clave. Sin la clave privada, el token no vale.
- mTLS: el token queda ligado al certificado cliente usado en la conexión TLS. Requiere footprint más controlado, pero simplifica validaciones servidoras.
Imágenes para embeber
- DPoP (diagrama de flujo, Okta):
- mTLS (secuencia, Auth0):
Puntos clave
- El host (no el modelo) es el cliente OAuth.
- El header Authorization y la prueba DPoP o el canal mTLS se inyectan fuera del prompt.
- Usa indicadores de recurso y audiencia correctos en la emisión del token.
2) Phantom token en gateway API
Objetivo: ocultar claims y reducir exposición de credenciales en el perímetro.
Patrón en el que el cliente presenta un token opaco; un gateway lo introspecciona y emite un JWT interno solo para tráfico intra‑perímetro. Así evitas que el agente o herramientas vean claims sensibles y puedes aplicar políticas uniformes en downstream.
Imagen para embeber
- Phantom token (Curity):
Puntos clave
- DPoP o mTLS entre host y gateway.
- Introspección en gateway y JWT interno con audiencia específica para microservicios.
- Trazabilidad por identidad del llamador y por herramienta.
3) Delegación segura con Token Exchange
Objetivo: evitar el token passthrough cuando el MCP actúa como proxy hacia terceros.
Usar un servicio de intercambio de tokens para canjear el token del host por otro token con audiencia y scopes específicos para la API downstream. El MCP nunca reenvía tokens del usuario; obtiene credenciales delegadas con privilegios mínimos y tiempo de vida corto.
Puntos clave
- Scopes reducidos por operación.
- Audience alineada con el recurso de destino.
- Revocación efectiva y rotación frecuente.
4) Firmas HTTP fuera de banda
Objetivo: garantizar integridad y autenticidad del mensaje sin exponer secretos al modelo.
Implementar HTTP Message Signatures para firmar partes relevantes de la petición (método, ruta, fecha, cabeceras seleccionadas, incluida Authorization) y añadirlas en Signature y Signature‑Input. La firma se genera en el host con una clave que el servidor MCP conoce o puede verificar. Previene replay y manipulación de mensaje por intermediarios.
Puntos clave
- El modelo nunca ve material de autenticación.
- Verificación determinista en el servidor MCP.
- Compatible con DPoP o mTLS.
5) Enclaves/TEE para claves y política
Objetivo: elevar el coste de ataque sobre material criptográfico y controles.
Cuando el contexto lo exige, ejecutar el MCP o su módulo de firma dentro de un TEE (SGX, SEV, Nitro Enclaves). La clave privada no sale del enclave, las validaciones de política se ejecutan dentro y los logs críticos pueden firmarse. No elimina bugs, pero reduce drásticamente el exfiltration surface.
Arquitecturas recomendadas
A) Host ↔ MCP con DPoP + Gateway con phantom token ↔ APIs internas
[Host] -- OAuth2 + DPoP --> [AS]
[Host] -- Authorization + DPoP --> [MCP]
[MCP] -- token opaco --> [API Gateway]
[Gateway] -- introspection --> [JWT interno] --> [APIs]
Ventajas: el token robado no sirve, el modelo no ve credenciales, policies centralizadas en el gateway y observabilidad clara.
B) MCP como proxy hacia terceros con token exchange
[Host] -- DPoP/mTLS --> [MCP]
[MCP] -- Token Exchange --> [AS del tercero]
[MCP] -- Bearer reducido (aud=tercero) --> [API del tercero]
Ventajas: elimina passthrough, reduce privilegios y acota responsabilidad por salto.
C) Firmas HTTP fuera de banda
Se superpone a A o B. El host firma cada petición y el MCP valida. Evita manipulación de headers sensibles y replay.
Checklist operativo
- Identidad del servidor MCP
- Autenticación mutua. Certificados o claves registradas previamente.
- Validación de audiencia y resource en todos los tokens entrantes.
- Prohibir token passthrough.
- Tokens y canal
- DPoP por defecto en clientes públicos. mTLS donde sea posible.
- Token exchange para delegación hacia terceras APIs.
- Vida corta, revocación efectiva y rotación de refresh tokens.
- Supply chain y registro
- Repositorios verificados, paquetes firmados, SBOM y análisis de dependencias.
- Política de instalación con allow‑list; denegar instalaciones sugeridas por el modelo.
- Aislamiento y permisos
- Contenedores por servidor MCP de terceros.
- Principio de mínimo privilegio en scopes y recursos.
- Controles de egreso y cuotas por herramienta.
- Sesiones y eventos
- No usar sesión como autenticación. Vincular sesión a identidad.
- IDs impredecibles, expiración corta, rotación y verificación en cada evento.
- Trazabilidad
- Logs por identidad y por herramienta.
- Correlación de llamadas host → MCP → downstream.
- Alertas por patrones anómalos de uso de herramientas y de egreso.
Snippets de referencia
Solicitud de token con DPoP
# Prueba DPoP firmada con clave del cliente
DPOP="$(make_dpop_proof POST https://as.example.com/oauth/token <jwk>)"
curl -s -X POST https://as.example.com/oauth/token \
-H "DPoP: ${DPOP}" \
-d "grant_type=authorization_code&code=$CODE&resource=https%3A%2F%2Fmcp.example"
HTTP Message Signatures (cabeceras)
Signature-Input: sig1=("@method" "@target-uri" "authorization");keyid="client-key-01";created=1739900000
Signature: sig1=:BASE64(RSA-PSS-SHA512(canonical-form-of-components)):
🧩 Recapitulación
Cosas que NO ❌ han funcionado:
❌ Confiar en tokens Bearer directos entre el cliente y el MCP. En entornos reales derivan en token passthrough, pérdida de control y suplantación del usuario.
❌ Permitir que el modelo gestione o vea cabeceras de autenticación: introducir material sensible en el prompt expone la identidad.
❌ Reutilizar sesiones o session_id
como mecanismo de autenticación. Los agentes y herramientas pueden reaprovecharlas sin control.
❌ Instalar servidores MCP desde repositorios o nombres no verificados. Los ataques de typosquatting y rug-pull siguen siendo el vector principal.
❌ Delegar la autenticación en terceros sin validar audiencia (aud
) ni recurso (resource
): genera vulnerabilidad tipo confused-deputy.
Cosas que SÍ ✅ han funcionado:
✅ Aplicar sender-constrained tokens (DPoP o mTLS) para asegurar que el token solo sirve en el canal legítimo.
✅ Implementar token exchange (RFC 8693) para delegar con scopes reducidos, evitando reenvío de credenciales originales.
✅ Usar phantom tokens en gateways API, ocultando claims y reforzando control interno.
✅ Firmar peticiones con HTTP Message Signatures y mantener las cabeceras de autenticación fuera de banda.
✅ Ejecutar servidores MCP en entornos aislados (contenedores o TEE) y con política inmutable de validación.
✅ Mantener auditoría y trazabilidad por identidad, no por herramienta, con logs firmados o correlacionados.
MCP facilita integrar agentes con herramientas y datos de forma dinámica, pero no está diseñado con la seguridad por defecto. La arquitectura debe impedir que la identidad del usuario quede a merced del modelo o de terceros. Con sender‑constrained tokens, delegación controlada, firmas fuera de banda, aislamiento y una cadena de suministro verificada, el coste de ataque se eleva y las suplantaciones pasan de ser triviales a improbables en explotación real.