← Blog
13 de julio, 2026 · 11 min

Autorización en MCP: OAuth 2.1 para agentes autónomos

Una llamada a una tool es una petición para ejecutar código en la máquina de otro. La spec de autorización de MCP decide quién puede hacerla. Para un agente autónomo que nunca tiene un humano que haga clic en "permitir", esa decisión es toda la frontera de seguridad.

El Model Context Protocol creció sobre stdio: un cliente lanza un servidor como subproceso, hablan por pipes y la confianza se hereda del sistema operativo. Ese modelo se rompe en cuanto el servidor vive en otro host. El MCP remoto es como los agentes alcanzan tools que no son suyas — una API de pagos, un vector store, el feed de datos de un competidor. Y un endpoint de tool remoto sin auth es simplemente una puerta abierta.

Así que la spec hizo lo disciplinado. En vez de inventar un esquema de tokens a medida, declaró que un servidor MCP protegido es un resource server OAuth 2.1 y un cliente MCP es un cliente OAuth 2.1. Todo lo demás se deriva de esa única frase. Este texto recorre el flujo normativo tal como está escrito en la especificación de autorización oficial, y después hace la pregunta que nos importa: qué significa cuando el cliente es un agente que paga por llamada, no una persona en un navegador.

Los roles, y por qué se separan

OAuth tiene tres actores, y la spec de MCP los mapea con precisión:

La separación es el punto. Una revisión de junio de 2025 de la spec redujo deliberadamente a los servidores MCP a solo resource servers. La emisión de tokens y la gestión de clientes se delegaron a authorization servers dedicados. Eso significa que el autor de una tool no construye login, consentimiento ni rotación de tokens — se apoya en Auth0, Keycloak, Okta o su propio IdP, y gasta su atención en validar lo que llega. Menos código en la ruta de seguridad es menos superficie de ataque.

Una condición de borde que vale la pena decir: la autorización es OPCIONAL, y está acotada a transportes HTTP. Sobre stdio, la spec dice explícitamente que no se siga — hay que sacar las credenciales del entorno. Así que todo lo de abajo es sobre el caso remoto, que es exactamente con el que se topan los agentes autónomos.

El 401, y cómo empieza el descubrimiento

El flujo empieza con un fallo. El cliente manda una petición MCP sin token; el servidor la rechaza. Pero el rechazo es informativo — lleva el mapa hacia el authorization server.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
                         scope="files:read"

Dos cosas viajan en ese header. Primero, una URL resource_metadata. Segundo, una pista opcional de scope que le dice al cliente el permiso mínimo que necesita esta operación. Se espera que el cliente trate ese scope desafiado como autoritativo para la petición actual y no asuma ninguna relación con el scopes_supported anunciado por el servidor.

La URL resource_metadata apunta a un documento de OAuth 2.0 Protected Resource Metadata, definido en RFC 9728. Los servidores MCP DEBEN implementarlo; los clientes MCP DEBEN usarlo para el descubrimiento. Esto reemplazó un esquema anterior de endpoints por defecto adivinados (/authorize, /token, /register) — adivinar es frágil, y mandatar un documento de descubrimiento no lo es.

El documento vive en una ruta well-known y, como mínimo, nombra el recurso y apunta a sus authorization servers:

// GET https://mcp.example.com/.well-known/oauth-protected-resource
{
  "resource": "https://mcp.example.com/mcp",
  "authorization_servers": ["https://auth.example.com"],
  "scopes_supported": ["files:read", "files:write"]
}

De ahí el cliente busca la metadata del propio authorization server — vía RFC 8414 (OAuth Authorization Server Metadata) o OpenID Connect Discovery — para aprender los endpoints reales de authorize y token. Los clientes DEBEN soportar ambos mecanismos de descubrimiento. Ninguna ruta hardcodeada en ningún lado.

Conseguir un client_id sin pre-registro

Aquí hay un problema genuinamente difícil para los agentes. El OAuth clásico asume un cliente registrado de antemano y con un client_id en mano. Un agente autónomo que descubre una tool que nunca ha visto no tiene tal registro. La spec ofrece tres rutas, y el orden te dice hacia dónde va.

// Ruta 1

Client ID Metadata Documents (CIMD)

El cliente usa una URL https como su client_id. El authorization server detecta la forma de URL, busca un documento JSON de metadata desde ella y valida los redirect_uris declarados. Sin llamada de registro. Este es el SHOULD — la ruta recomendada por defecto en el draft actual, definida en draft-ietf-oauth-client-id-metadata-document-00.

// Ruta 2

Dynamic Client Registration (RFC 7591)

El cliente hace POST a un endpoint /register y recibe credenciales. Soportado como MAY, pero la spec ahora marca DCR como deprecado, retenido solo para authorization servers que aún no hablan CIMD.

// Ruta 3

Pre-registro

El caso clásico: el cliente ya tiene un client_id emitido fuera de banda. Bien cuando controlas ambos extremos.

El movimiento de DCR hacia CIMD es una apuesta a la escala. El registro dinámico crea una fila de base de datos por cliente en el authorization server — un vector de spam y agotamiento de almacenamiento cuando los clientes son millones de agentes efímeros. Una URL auto-descriptiva que el AS busca y valida on-demand no carga ese estado. Es el mismo instinto que empujó a MCP hacia una arquitectura de servidor sin estado: cuando la población de agentes no tiene cota, el estado por agente en el lado del servidor es un pasivo.

PKCE, y validar quién respondió

Una vez que el cliente tiene un client_id, la petición de autorización en sí es OAuth 2.1 estándar: PKCE es obligatorio. El cliente genera un code verifier, manda su code_challenge por adelantado y prueba posesión con el code_verifier en el token endpoint. Como la mayoría de los clientes MCP son públicos — CLIs, apps de escritorio, agentes sin un lugar seguro donde guardar un secreto — PKCE no es endurecimiento opcional; es lo que se interpone entre un authorization code interceptado y un token robado.

La spec añade una comprobación más que es fácil pasar por alto e importante para agentes: validación de issuer según RFC 9207. Antes de empezar el flujo, el cliente registra el issuer esperado desde la metadata validada del authorization server. Cuando vuelve la respuesta de autorización, el cliente compara el iss devuelto contra ese valor registrado usando comparación estricta de strings — sin case folding, sin normalización de slash final. Esto defiende contra mix-up attacks, donde un authorization server malicioso engaña a un cliente para que mande un code destinado a otro servidor honesto. Un agente malabareando tokens de una docena de proveedores de tools es exactamente el blanco que tal ataque busca.

El parámetro resource: tokens que solo encajan en una cerradura

Esta es la cláusula que separa el modelo de MCP de los setups ingenuos de bearer token, y vale la pena leerla con cuidado.

Los clientes MCP DEBEN implementar Resource Indicators for OAuth 2.0, RFC 8707. Cada petición de autorización y cada petición de token lleva un parámetro resource que nombra el servidor MCP exacto para el que es el token, por su URI canónica:

// las peticiones de authorization + token ambas llevan:
&resource=https%3A%2F%2Fmcp.example.com%2Fmcp

Y del lado receptor, el servidor DEBE validar que un access token entrante fue emitido específicamente para él como audiencia prevista. Si el token se acuñó para un recurso distinto, el servidor lo rechaza con un 401. La regla se enuncia de tres formas para enfatizar: un servidor "DEBE aceptar solo tokens válidos para uso con sus propios recursos" y "NO DEBE aceptar ni transitar ningún otro token."

Los tokens ligados a audiencia convierten una credencial robada de una llave maestra en una llave que encaja en una sola cerradura. Si el token de un agente para una tool de resumen se filtra, no puede reproducirse contra la tool de pagos del agente, porque el servidor de pagos verá la audiencia equivocada y lo rechazará. Para una flota de agentes cada uno con tokens a muchos servicios, esa contención es la diferencia entre una tool comprometida y una brecha de flota completa.

La prohibición del confused deputy

El requisito más sutil es sobre lo que un servidor no debe hacer con un token que tiene. Cuando un servidor MCP necesita llamar a una API upstream — digamos que fronterea un servicio de búsqueda de terceros — debe obtener su propio token para ese upstream, actuando como cliente OAuth por derecho propio. NO DEBE pasar directamente el token que recibió del cliente MCP.

Sáltate esa disciplina y construyes un confused deputy: un servidor con privilegios upstream amplios que un llamante de menor privilegio puede engañar para que actúe en su nombre. El token del cliente estaba scoped y con audiencia para el servidor MCP, no para lo que sea que el servidor hable a continuación. Reusarlo downstream lava la identidad del cliente hacia los privilegios del servidor. La regla de audiencia de arriba es lo que hace la prohibición aplicable — un token pasado directamente fallaría la propia comprobación de audiencia del upstream, si el upstream sigue la misma spec.

Esta es la misma clase de amenaza que mapeamos en el modelo de amenazas de seguridad de agentes: privilegio que fluye lateralmente por una cadena de servicios porque nadie re-estableció la identidad en cada salto. RFC 8707 más la prohibición de passthrough es el arreglo a nivel de protocolo.

Step-up authorization, o mínimo privilegio en runtime

Los agentes rara vez necesitan todos sus permisos a la vez. La spec soporta adquirirlos de forma incremental. Cuando un cliente llama con un token que carece de un scope necesario, el servidor responde 403 Forbidden con error="insufficient_scope" y nombra el scope faltante:

HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer error="insufficient_scope",
                         scope="files:write",
                         resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource"

El cliente entonces corre un flujo de step-up, pidiendo la unión de sus scopes previamente otorgados y los recién desafiados, y reintenta — un número acotado de veces, y luego se rinde. La acumulación de scopes es responsabilidad del lado del cliente, lo que mantiene al servidor sin estado sobre el conjunto de permisos de ningún cliente en particular. Un agente puede empezar con acceso de solo lectura y escalar a escritura solo cuando una tarea realmente lo exige, con cada escalada visible en el rastro de consentimiento del authorization server.

Qué significa para LLM4Agents

LLM4Agents se sitúa en una unión específica: un gateway compatible con OpenAI donde los agentes pagan por llamada en stablecoins sobre x402. La autorización de MCP es la mitad de identidad de un problema de dos partes cuya mitad de pago ya operamos.

Las dos capas componen limpiamente. El pago responde "¿se pagó por esta llamada?" — x402 devuelve un 402 con términos, el agente firma una autorización EIP-3009, el facilitator liquida. La autorización responde "¿está permitido este llamante?" — MCP devuelve un 401 con un puntero de descubrimiento, el agente presenta un token OAuth ligado a audiencia. Un 402 y un 401 son preguntas distintas, y una plataforma de agentes seria responde ambas. Un agente que paga pero no puede probar su identidad es una wallet sin nombre; un agente que se autentica pero no puede pagar se estanca en el paywall.

En concreto, tres propiedades de la spec mapean sobre cosas que nos importan. Los tokens ligados a audiencia significan que una credencial filtrada de una tool no puede reproducirse por toda una flota — contención que queremos por defecto. La prohibición del confused deputy significa que el gateway, cuando reparte una petición a proveedores de modelos o tools downstream, debe acuñar sus propias credenciales upstream en vez de lavar las del llamante — que es como una capa de routing debería comportarse de todos modos. Y el giro de CIMD sobre DCR refleja nuestra propia preferencia por la ausencia de estado: cuando la población de clientes es un enjambre de agentes de vida corta, las filas de registro por agente no escalan, y las identidades de cliente auto-descriptivas sí.

Cómo mantenerse en la frontera

La spec es un blanco en movimiento — sigue marcada como draft, y las revisiones a lo largo de 2025 y 2026 cambiaron los defaults de registro y la mecánica de descubrimiento más de una vez. Seguirle el paso es el trabajo. En concreto, en orden:

  1. Hablar auth del lado resource server en los endpoints MCP. Implementar RFC 9728 Protected Resource Metadata y validación de audiencia de RFC 8707 en cualquier superficie MCP que expongamos, para que un token emitido para nuestro resumidor nunca pueda reproducirse contra nuestras tools de facturación. Este es el primer movimiento de mayor apalancamiento.
  2. Preferir CIMD, mantener DCR como fallback. Soportar Client ID Metadata Documents como la ruta de registro por defecto para agentes que llegan a nuestras tools, con registro dinámico RFC 7591 solo para authorization servers que aún no pueden hacer CIMD. No construir una base de datos de registro por agente de la que nos arrepintamos.
  3. Nunca pasar tokens directamente. Cuando el gateway llama a proveedores de modelos upstream, actúa como su propio cliente OAuth con sus propias credenciales — nunca reenviando el token de un llamante. Hornear la prohibición del confused deputy en la capa de routing, no en un checklist.
  4. Aplicar validación de issuer RFC 9207 del lado cliente. Donde sea que nuestra infraestructura actúe como cliente MCP contra tools de terceros, registrar y comparar estrictamente el issuer esperado, para que un mix-up attack no pueda redirigir el authorization code de un proveedor hacia otro.
  5. Ligar identidad a pago. La frontera es una petición que lleva tanto un token OAuth ligado a audiencia como una autorización de pago x402 — llamante probado, pago liquidado, en un solo round trip. Emparejar la auth de MCP con identidad de agente ERC-8004 para que la reputación, no solo un token, controle el acceso a tools de alto valor.

El gateway que acierta en ambas mitades — quién eres y si pagaste — es el que los agentes autónomos confiarán con su dinero y sus credenciales. Ese emparejamiento es el producto.

Construye agentes que se autentican y pagan

Gateway compatible con OpenAI, liquidación en stablecoins y una superficie MCP construida para llamantes autónomos.

Registrar un agente