Volver
Kevin Riedl

12 min de lectura · 23 de julio de 2026

Siguiente

Arquitectura de autorización MCP para empresas: un diseño de referencia multi-tenant

La especificación del Model Context Protocol por fin dice algo concreto sobre autorización: usar OAuth 2.1, vincular cada token a una audiencia específica con resource indicators y no reenviar nunca un token del cliente a una API downstream. Los requisitos son reales. El problema es que están repartidos entre la especificación central, un documento de buenas prácticas de seguridad y media docena de RFC del IETF, y casi toda página que rankea para estos términos es una checklist de un proveedor de seguridad que se detiene en el caso de un solo servidor.

Este es el diseño de referencia que usamos cuando un cliente necesita un servidor MCP que sirva a más de un tenant, se conecte a un proveedor de identidad empresarial y sobreviva a una revisión de seguridad de compras. Es neutral respecto al proveedor, está anclado a la revisión 2025-11-25 de la especificación y dibuja el diagrama que nadie más dibuja: toda la frontera de confianza, del proveedor de identidad al plano de datos por tenant. Escrito a partir del trabajo de Wavect en productos de IA y endurecimiento de seguridad.

¿Diseñas un servidor MCP empresarial?

 Habla con Wavect

Quién es responsable de qué: el servidor MCP es un resource server, no un authorization server

El error más común es construir el servidor MCP como su propio sistema de login. No lo es. Bajo la especificación actual, el servidor MCP es un resource server de OAuth 2.1. Su trabajo es validar tokens, no emitirlos. Un authorization server aparte, que en una empresa es tu proveedor de identidad (Entra ID, Okta, Auth0, Keycloak, Ping), interactúa con el usuario y emite los tokens de acceso.

Esta separación es reciente. La primera especificación de autorización (2025-03-26) esperaba que el servidor MCP actuara como authorization server y resource server a la vez. La revisión 2025-06-18 separó los roles mediante la pull request 284, y esa separación es lo que hace posible el single sign-on empresarial. El authorization server aún puede estar junto al resource server, pero la responsabilidad obligatoria del servidor MCP es validar tokens. Acierta con este modelo de roles y todo lo demás encaja. Fállalo y reconstruyes identidad, mal.

¿Qué exige realmente la especificación actual?

Dos advertencias antes de la tabla. Primera, la autorización en MCP es opcional y solo está definida para transportes HTTP. Un servidor tras un transporte STDIO no debería seguir esta especificación; toma las credenciales del entorno. Segunda, OAuth 2.1 sigue siendo un borrador del IETF, no un RFC publicado, así que no cites un número de RFC para él. Esta es la superficie de estándares de la revisión 2025-11-25.

EstándarReferenciaRol en MCPNivel
OAuth 2.1draft-ietf-oauth-v2-1Framework centralAuth server MUST
Protected Resource MetadataRFC 9728El servidor apunta al cliente hacia su auth serverResource server MUST
Resource IndicatorsRFC 8707Vincula el token a una audienciaCliente MUST
Authorization Server MetadataRFC 8414Descubrimiento del auth serverMUST (esto u OIDC)
OpenID Connect DiscoveryOIDC Core 1.0Descubrimiento alternativo del auth serverMUST (esto o 8414)
PKCEOAuth 2.1 Sec 7.5.2Protege el authorization codeCliente MUST, S256
Client ID Metadata Documentsdraft-ietf-oauth-client-id-metadata-documentURL como client_idSHOULD (nuevo en 2025-11-25)
Dynamic Client RegistrationRFC 7591Registro automático de clientesMAY (era SHOULD)
Uso de bearer tokenRFC 6750Challenge e insufficient_scopeReferenciado

Fíjate en los dos cambios de versión que hacen tropezar a la gente. La revisión 2025-11-25 rebajó Dynamic Client Registration de SHOULD a MAY y añadió un método PKCE S256 obligatorio, además del requisito de que el cliente verifique el soporte de PKCE antes de empezar. Si el metadata del auth server no anuncia code_challenge_methods_supported, un cliente conforme debe rechazar iniciar el flujo.

¿Cómo funciona el flujo de autorización de principio a fin?

Todo el handshake es un paso de descubrimiento seguido de un authorization code flow estándar. El cliente llega al servidor sin token, le dicen dónde autenticarse, se autentica y vuelve con un token acuñado para este servidor concreto.

Secuencia de autorización OAuth 2.1 de MCP: challenge 401, descubrimiento del protected-resource metadata, authorization code flow con PKCE y resource indicator, y luego un bearer token vinculado a la audiencia que el resource server valida

Dos detalles obligatorios viven dentro de ese diagrama. En el challenge, el servidor debe devolver 401 Unauthorized con una cabecera WWW-Authenticate que lleva la URL resource_metadata, según RFC 9728. La revisión 2025-11-25 también deja al cliente sondear directamente la URI well-known. En las peticiones de authorization y de token, el cliente debe enviar un parámetro resource con la URI canónica del servidor MCP, y debe enviarlo aunque el auth server no diga soportarlo.

¿Por qué se prohíbe el token passthrough y cómo validas la audiencia?

Este es el corazón de seguridad de la especificación, y es donde fallan la mayoría de los servidores caseros. La regla es contundente: el servidor MCP debe validar que cada token de acceso se emitió para él como audiencia prevista, y debe rechazar cualquier otra cosa. No debe aceptar un token acuñado para otro servicio ni reenviar el token que recibió a una API downstream. Ese último antipatrón es el token passthrough, y la especificación lo prohíbe sin rodeos.

La razón es el problema del confused deputy. Si tu servidor acepta y reenvía tokens que no verificó, un token filtrado o emitido para un servicio se convierte en llave maestra de otro, se saltan los rate limits basados en audiencia y el rastro de auditoría downstream muestra la identidad equivocada. Validar la audiencia es una comprobación de un claim, y es la línea entre un resource server y una responsabilidad legal.

on every tool call:
  token = bearer_from_authorization_header()   # never from a session
  claims = verify_signature(token, jwks_of(trusted_issuer))
  assert claims.iss == expected_issuer          # pinned per tenant
  assert this_server_uri in claims.aud          # RFC 8707 audience
  assert not expired(claims) and not before(claims)
  assert required_scope_for(tool) in claims.scope
  tenant = claims["tenant"] or claims["org_id"]
  enforce_tenant(tenant)                         # every query, every secret

Fíjate en lo que no aparece: ninguna búsqueda de sesión para autenticar. La especificación es explícita en que los servidores deben verificar cada petición entrante y no deben usar sesiones para autenticar. Los identificadores de sesión, si los usas, deben ser no deterministas y estar vinculados a la identidad del usuario, para que un identificador adivinado no pueda suplantar a otro tenant.

¿Cómo llega el servidor a las APIs downstream sin filtrar el token?

Si el servidor MCP necesita llamar a una API downstream, actúa como cliente OAuth ante esa API y usa un token aparte acuñado por el authorization server upstream. La especificación te dice qué no hacer (no reenviar el token entrante) pero deja el cómo al ecosistema. El patrón dominante es el token exchange, definido en RFC 8693: el servidor cambia el token entrante, cuya audiencia es el servidor MCP, por un token nuevo cuya audiencia es la API downstream.

El servidor juega aquí un doble rol: resource server ante el cliente, cliente OAuth ante la API. Prefiere la delegación a la suplantación, para que el usuario original quede en el claim sub y la cadena de actuación quede registrada en el claim act, que es lo que mantiene honesto tu rastro de auditoría a través del salto. El token exchange y los flujos on-behalf-of quedan fuera de la especificación central de MCP, así que trátalos como responsabilidad del proveedor de identidad o del gateway, no como un requisito de MCP.

¿Cómo es la arquitectura de referencia multi-tenant?

Esta es la topología. Un proveedor de identidad emite tokens vinculados a una audiencia, con un realm por tenant. Los clientes presentan esos tokens a un resource server o gateway compartido dentro de la frontera de confianza empresarial. El servidor valida la audiencia, aplica el scope por herramienta, fija el realm del tenant y solo entonces llega a herramientas, datos y APIs downstream, cada uno aislado por tenant.

Arquitectura de autorización MCP multi-tenant: los clientes por tenant reciben tokens vinculados a una audiencia de un proveedor de identidad compartido, los presentan a un gateway MCP que valida la audiencia, aplica el scope por herramienta y fija el realm del tenant, y llegan a las APIs downstream mediante token exchange RFC 8693, mientras el plano de datos, el credential vault y el audit log siguen siendo por tenant

El error en la mayoría de los textos multi-tenant es tratar el aislamiento como un asunto de base de datos. No lo es. La multitenencia hay que aplicarla en cada capa, y la identidad del tenant sale de un claim de token verificado, nunca de una entrada de herramienta que el modelo pueda influir. La tabla de abajo es la checklist que recorremos por capa.

CapaControl de aislamientoFallo si se omite
IdentidadFijar issuer y realm por tenant; rechazar tokens de otros realmsEl tenant A entra por el realm del tenant B
TokenValidar audiencia (RFC 8707) y caducidad en cada peticiónSe acepta un token acuñado en otro sitio
ScopeScopes de mínimo privilegio mapeados desde grupos y roles del IdPUn rol de lectura ejecuta una escritura
HerramientaFiltrar las herramientas visibles por tier de tenant y scopeEl agente descubre una herramienta que no puede usar con seguridad
CredencialSecretos por tenant en un vault, opacos al modelo y al clienteLa API key de un tenant sirve a otro
DatosRow-level security basada en el claim del tenantLectura de filas entre tenants
AuditoríaLogs por tenant, inmutables, con correlation IDsSin atribución durante un incidente
Kevin Riedl

"La identidad del tenant es un claim de token verificado. En el momento en que sale de un argumento de herramienta que el modelo puede escribir, tu aislamiento es puro teatro."

¿Cómo funcionan los scopes por herramienta y la autorización step-up?

El protocolo central gestiona los scopes a nivel de OAuth, no por herramienta individual, así que la autorización por herramienta real la construyes encima. La especificación te da las primitivas. Empieza en mínimo y evita scopes ómnibus como all o full-access. Cuando una herramienta necesita más de lo que concede el token actual, la revisión 2025-11-25 define un step-up limpio: el servidor devuelve 403 con WWW-Authenticate: Bearer error="insufficient_scope" y el scope requerido, el cliente ejecuta una autorización incremental solo para ese scope y reintenta.

En la práctica mapeamos grupos del proveedor de identidad y roles SCIM a scopes, y luego condicionamos cada herramienta a un scope requerido. Un rol de analista lleva invoices:read y ve las herramientas de lectura; nunca lleva ledger:write. Es la misma disciplina que aplicamos en una revisión de autorización, y es lo que un equipo de compras de verdad prueba.

¿Cómo añades SSO empresarial a un servidor MCP?

Hay dos formas, y la elección determina la mayor parte de tu coste operativo.

La primera es OAuth por servidor: cada servidor MCP apunta su metadata authorization_servers al proveedor de identidad corporativo. Limpio para uno o dos servidores, repetitivo a escala de flota. La segunda es un gateway MCP: una única entrada con políticas aplicadas delante de cada servidor, que centraliza descubrimiento, validación de tokens, mapeo de scopes, token exchange y auditoría. Para una empresa con muchos servidores y muchos tenants, el gateway suele ser la respuesta correcta porque te da un solo sitio donde aplicar el aislamiento y un solo sitio donde auditar.

Sobre protocolos: OIDC es de primera clase en la revisión 2025-11-25, que exige que el auth server soporte metadata RFC 8414 u OpenID Connect Discovery, y que los clientes intenten ambos. En MCP no hay SAML nativo. Una empresa solo-SAML hace de puente a través de su proveedor de identidad o de un broker que expone una fachada OAuth u OIDC para el servidor MCP.

¿Cómo gobiernas el registro de clientes y los tiempos de vida de las credenciales?

Dynamic Client Registration era el punto débil de los primeros despliegues porque dejaba que clientes arbitrarios se registraran. La revisión 2025-11-25 lo rebaja a MAY y prefiere un modelo de tres niveles: credenciales preregistradas para clientes conocidos, luego Client ID Metadata Documents donde el cliente usa una URL HTTPS como client_id, y luego DCR como fallback. Si permites cualquiera de los dos últimos, mete los issuers en una allowlist y vigila los riesgos de SSRF y de redirect a localhost que menciona la especificación. Las empresas deberían atar el registro a un tenant y pasar los clientes desconocidos por una cola de revisión de admin.

Los tiempos de vida de las credenciales siguen OAuth 2.1: emitir tokens de acceso de vida corta, rotar los refresh tokens de los clientes públicos, guardar los tokens de forma segura, mantener los tokens fuera de los query strings de la URL y enviar el bearer token en cada petición. Valores por defecto concretos con los que arrancamos:

CredencialVida típicaRotación
Token de acceso (cliente a servidor)5 a 15 minutosReacuñar desde el refresh token
Refresh token (cliente público)Horas a días, deslizanteRotar en cada uso
Token downstream (RFC 8693)Minutos, por llamada o sesiónReintercambiar, no cachear en amplio
Secreto por tenant en el vaultLarga, pero revocableProgramada más ante sospecha de fuga

¿Qué eventos de auditoría debes capturar?

La especificación central no tiene un requisito propio de logging de auditoría, pero el análisis del token passthrough construye el argumento por ti: el passthrough rompe el rastro de auditoría porque los logs downstream muestran la identidad equivocada. En un sistema multi-tenant, la auditoría es cómo demuestras que el aislamiento aguantó. Registra estos, por tenant, con un correlation ID que sobreviva al salto downstream.

  • Resultados de validación de tokens: aceptado, rechazado por audiencia, rechazado por issuer, caducado.
  • Decisiones de autorización: herramienta invocada, scope requerido, scope concedido, allow o deny.
  • Eventos de step-up: scope solicitado y el subconjunto concedido.
  • Token exchange: qué audiencia downstream se acuñó, para qué subject y qué actor.
  • Contexto de tenant: el claim de tenant verificado en cada entrada, para que una consulta sea atribuible a un tenant, un usuario y una herramienta.

Por servidor, gateway o identidad gestionada: ¿cuál eliges?

Una matriz de decisión rápida para las tres topologías viables.

EnfoqueMejor cuandoCoste
OAuth por servidorUno o dos servidores, un tenantPoco setup, flojo a escala
Gateway MCPMuchos servidores o muchos tenantsMás setup, un punto de aplicación
Integración con IdP gestionadoYa vives en Entra u OktaLock-in de proveedor, compliance más rápido

Pasar de un servidor de un solo tenant a uno multi-tenant no es una reescritura si lo secuencias: primero introduce el claim de tenant y fija el issuer, mueve los secretos a un vault por tenant, añade row-level security basada en el claim, luego filtra la visibilidad de herramientas y enciende la auditoría por tenant. Cada paso se puede entregar y probar por su cuenta. Prueba el aislamiento de forma adversaria: reproduce el token del tenant A contra los datos del tenant B y confirma que se rechaza en la capa de token, no solo que se filtra en la capa de consulta.

Reflexiones finales

La especificación de autorización de MCP te da tres requisitos duros: OAuth 2.1 como marco, tokens vinculados a una audiencia mediante resource indicators y nada de token passthrough. Todo lo demás que importa a una empresa, aislamiento multi-tenant, scopes por herramienta, acceso delegado downstream y auditoría, vive por encima de la especificación y es tuyo para diseñarlo. Trata el servidor MCP como un resource server que valida y aplica, mantén la identidad del tenant en un claim verificado y registra lo suficiente para demostrar que el aislamiento aguantó. Haz eso y un servidor MCP deja de ser el eslabón más débil de tu stack de agentes.

Fuentes y lecturas adicionales

Hardening antes de la verificación independiente

¿Preparas una aplicación para un pentest independiente o una revisión de seguridad de cliente? Wavect endurece autorización, secretos, rutas de fallo y cobertura de regresión, y después ayuda a tu equipo a cerrar los hallazgos.

Rutas de servicio relevantes:

Tu bandeja, sin ruido

Sigue el trabajo que te importa

Recibe un correo breve cuando publiquemos algo nuevo. Sigue todo el blog o solo los temas que te interesan.

¿Qué quieres recibir?
Elige tus temas

Gratis, doble opt-in y sin píxeles de seguimiento.

Volver
Kevin Riedl

12 min de lectura · 23 de julio de 2026

Siguiente