03Autenticación

Sección 03

Autenticación

.md

Su servidor MCP es un endpoint expuesto a internet que puede leer y escribir en sus sistemas. La autorización es opcional en el estándar; en este contrato no lo es.

Hay dos niveles admitidos. Ambos son servidor a servidor: no hay usuario final, ni pantallas de consentimiento, ni OAuth de terceros.

Nivel 1 · OAuth 2.1 (recomendado)

Su servidor actúa como servidor de recursos OAuth 2.1. Asixto obtiene un token por credenciales de cliente y lo presenta en cada petición.

Requisitos:

#RequisitoExigencia
1Publicar metadatos de recurso protegido (RFC 9728) en /.well-known/oauth-protected-resourceDEBE en el nivel 1
2Responder 401 con WWW-Authenticate indicando el scope requerido cuando falta o es inválida la credencialDEBE
3Validar la audiencia del token (RFC 8707): rechazar todo token que no fue emitido para su servidorDEBE
4Exponer descubrimiento del servidor de autorización (RFC 8414 u OpenID Connect Discovery)DEBE
5Soportar documentos de metadatos de cliente (Client ID Metadata Documents)DEBERÍA

El registro dinámico de cliente (RFC 7591) quedó obsoleto en la revisión 2026-07-28 y se mantiene solo por compatibilidad. No lo requiera.

Cómo obtiene Asixto sus credenciales de cliente. Sin registro dinámico queda un solo camino, y es manual a propósito: usted crea en su servidor de autorización unas credenciales de cliente para Asixto —flujo de credenciales de cliente, con el scope mcp:tools— y registra el client_id y el secreto junto con la URL de su servidor, en la aplicación de Asixto (página 08). Las rota cuando quiera desde el mismo sitio; la rotación admite dos credenciales activas a la vez, igual que en el nivel 2. mcp:tools es el scope del contrato: es el que su servidor debe exigir y el que Asixto solicita.

Con el SDK de TypeScript

El paquete de Express trae las piezas hechas:

TypeScript
import {
  createMcpExpressApp,
  requireBearerAuth,
  mcpAuthMetadataRouter,
  getOAuthProtectedResourceMetadataUrl,
} from '@modelcontextprotocol/express';

const app = createMcpExpressApp();

// Publica los metadatos de recurso protegido (RFC 9728)
app.use(mcpAuthMetadataRouter({ /* su servidor de autorización */ }));

// Protege el endpoint MCP: valida Authorization: Bearer … con su verificador.
// `requiredScopes` es lo que hace que un token sin el scope del contrato reciba
// 403 `insufficient_scope` en vez de pasar.
app.use(
  '/mcp',
  requireBearerAuth({
    verifier: miVerificadorDeTokens,
    requiredScopes: ['mcp:tools'],
    resourceMetadataUrl: getOAuthProtectedResourceMetadataUrl(new URL('https://mcp.suempresa.com')),
  })
);

getOAuthProtectedResourceMetadataUrl(serverUrl) construye la URL que debe anunciar en la cabecera WWW-Authenticate.

Respuesta esperada sin credencial

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

Nivel 2 · Token rotable (mínimo aceptable)

Un token opaco emitido por usted, presentado como Authorization: Bearer ….

RequisitoExigencia
Longitud ≥ 32 bytes de entropíaDEBE
Caducidad declaradaDEBE
Dos credenciales activas simultáneas durante la rotaciónDEBE
Rotación sin intervención de AsixtoDEBE
401 (no 403 ni 500) cuando falta o es inválidoDEBE

Se admite para incorporación rápida y entornos de prueba. El registro la guardará cifrada y nunca la escribe en trazas.

Defensa en profundidad

Además del token:

  • TLS obligatorio con certificado válido. Sin excepciones, tampoco en pruebas.
  • Lista blanca de dominio: el Gateway llamará únicamente a la URL registrada del tenant.
  • Restricción por origen (opcional): puede limitar por el rango de direcciones del Gateway.
  • Validación de cabecera Host si su servidor también escucha en local: el SDK trae hostHeaderValidation para protección ante DNS rebinding.

Reglas duras de aislamiento

  1. Asixto nunca reenvía a su servidor un token de la plataforma Asixto. Su servidor solo recibe la credencial que usted mismo emitió. Esto evita que un servidor externo pueda actuar en nombre del tenant contra la plataforma.
  2. Un servidor registrado queda ligado a un único tenant. No debe responder por otra empresa, y el Gateway no comparte su catálogo con otros tenants.
  3. Sin secretos en las respuestas ni en los mensajes de error. El texto de error puede terminar leído en voz alta en una llamada.

Lista de verificación

  • Petición sin Authorization → 401 con WWW-Authenticate.
  • Token de otra audiencia → 401.
  • Token caducado → 401 (no 500).
  • Metadatos de recurso protegido accesibles y coherentes con la URL del servidor.
  • Rotación probada con las dos credenciales activas.
  • Ningún token en logs de su lado.