Authorization Server como PDP para MCP Tool-Scoped Access (guía práctica)

Portada técnica: Authorization Server como PDP y MCP Gateway como PEP aplicando audiencia y permisos de herramienta exactos.

Authorization Server como PDP para acceso tool-scoped en MCP

1) Resumen ejecutivo

En arquitecturas agentic con MCP, el error de seguridad más repetido es validar OAuth correctamente en el borde del servidor, pero no en el borde real de riesgo: la invocación de herramienta (tools/call). Resultado: token “válido” + planner probabilístico = privilegios operativos excesivos.

La estrategia más robusta hoy:

  • PDP en emisión (AS/IdP): decide permisos mínimos por intención.
  • PEP determinista en ejecución (gateway/runtime): valida JWT (iss, exp, firma, aud) y aplica autorización exacta por params.name.

Contrato de seguridad mínimo:

  1. Recurso ligado en aud (canonical URL).
  2. Herramienta ligada por identificador exacto (scope tokenizado o claim estructurado).
  3. Delegación OBO vía token exchange con downscoping monotónico.

Esto reduce confused deputy, sobreprivilegio y abuso inducido por prompt sin depender de “que el LLM se porte bien”.

2) Enmarcado del problema

2.1 Dónde se rompe el modelo de mínimo privilegio

Flujo típico inseguro:

  1. Cliente obtiene token para “el MCP”.
  2. Gateway verifica firma y expiración.
  3. Agente llega a tools/call con ese token.
  4. Se autoriza por “ser del servidor”, no por herramienta específica.

Consecuencia: el sistema delega una decisión sensible al comportamiento emergente del planner.

2.2 Riesgos concretos

  • Confused deputy: el agente actúa con privilegios superiores al propósito original.
  • Blast radius lateral: un token útil para lectura habilita escritura/destrucción en otro contexto.
  • Escalada por ambigüedad: matching laxo (contains) permite falsos positivos de scope.
  • Enumeración de superficie: tools/list abierto expone catálogo completo para pivote técnico o error de planificación.

2.3 Qué sí y qué no cubre esta propuesta

Sí cubre:

  • autorización determinista por recurso + herramienta;
  • control reproducible y auditable;
  • denegación fail-closed antes de ejecutar herramientas.

No cubre por sí sola:

  • validación semántica profunda de argumentos de negocio;
  • gobernanza HITL para acciones irreversibles;
  • replay sin controles de sender-constrained token (DPoP/mTLS).

3) Arquitectura de referencia

Arquitectura PDP/PEP para autorización tool-scoped en MCP
Arquitectura de referencia: decisión de permisos en el AS/IdP (PDP) y enforcement determinista en gateways (PEP).

3.1 Roles

  • AS/IdP (PDP): transforma identidad + intención + política en claims firmados.
  • Agent Gateway (PEP #1): controla acceso al endpoint del agente (audiencia de agente).
  • MCP Gateway (PEP #2): controla tools/call (audiencia MCP + permisos de tool).
  • MCP server(s): ejecutan solo tráfico pre-autorizado.

3.2 Invariantes

  1. Audience strictness: aud debe contener el recurso canónico del endpoint llamado.
  2. Tool exactness: params.name debe coincidir exactamente con permiso emitido.
  3. Monotonicidad en OBO: token downstream nunca amplía privilegios upstream.
  4. Fail-closed: duda o inconsistencia => DENY.

3.3 Representación de permisos

Opción A — scope plano (rápida de desplegar)

{
  "aud": "https://gw.example.com/mcp/payments",
  "scope": "mcp:tool:accounts.list mcp:tool:payments.transfer"
}

Requisito: parseo por espacios y comparación exacta por token.

Opción B — claim estructurado (recomendada para multi-recurso)

{
  "aud": [
    "https://gw.example.com/mcp/payments",
    "https://gw.example.com/mcp/crm"
  ],
  "tool_permissions": [
    {"rs":"https://gw.example.com/mcp/payments","name":"accounts.list"},
    {"rs":"https://gw.example.com/mcp/payments","name":"payments.transfer"},
    {"rs":"https://gw.example.com/mcp/crm","name":"crm.getCustomer"}
  ]
}

Ventaja: evita ambigüedad en aud[] y bloquea uso cruzado de tool en recurso incorrecto.

4) Secuencias de autorización (ALLOW/DENY)

4.1 ALLOW canónico

Secuencia ALLOW con audiencia correcta y herramienta permitida
Flujo ALLOW: token válido, audiencia correcta y coincidencia exacta de params.name.
  1. Cliente solicita token para recurso MCP específico (resource).
  2. AS emite JWT con aud y permisos mínimos por intención.
  3. Agente envía tools/call con params.name.
  4. PEP MCP valida JWT + aud + permiso exacto.
  5. Si todo coincide, forward al MCP server.

Resultado: ejecución autorizada y trazable.

4.2 DENY por audiencia

Secuencia DENY por mismatch de audiencia
Flujo DENY por aud: el PEP rechaza con 401 invalid_token y no ejecuta herramienta.

Token correcto criptográficamente, pero aud no incluye el recurso de ese endpoint.

Resultado: 401 invalid_token antes de evaluar la herramienta.

4.3 DENY por herramienta

aud correcto, pero params.name fuera de permisos emitidos.

Resultado: 403 insufficient_scope sin ejecución.

4.4 OBO/downscope en cadena agentic

Cliente -> agente con token upstream; agente intercambia por token downstream MCP (TTL corto y scopes mínimos).

Resultado: separación de privilegios por salto y reducción de superficie en caso de filtración.

5) Ejemplos prácticos (fallo y control)

Ejemplo A — Prompt injection intenta operación destructiva

Intención legítima: consultar saldo.

Tool permitida: accounts.list.

Planner propone por inyección: payments.transfer.

Evaluación PEP: payments.transfer no está en permisos.

Decisión: DENY determinista.

Ejemplo B — Substring bug en scope

Token trae scope="mcp:tool:payments.transfer.read".

Implementación insegura usa scope.contains("payments.transfer").

Ataque: se autoriza payments.transfer por coincidencia parcial.

Mitigación: tokenizar por espacios y comparar igualdad exacta del identificador esperado.

Ejemplo C — Multi-recurso (aud[]) sin binding (rs,tool)

Token válido para payments + crm, con lista plana de tools.

Riesgo: llamada a tool de payments sobre endpoint crm por error de routing o bug.

Mitigación: exigir tool_permissions con rs explícito y evaluar par (resource_id, tool_name).

Ejemplo D — Token passthrough sin exchange

Agente reusa token amplio del cliente directamente contra MCP.

Riesgo: hereda privilegio transitorio no previsto para el salto downstream.

Mitigación: RFC 8693 token exchange + TTL 60–300s + scopes mínimos por intención.

Ejemplo E — Enumeración en tools/list

tools/list abierto revela herramientas de administración no necesarias.

Mitigación recomendada:

  • modo ALLOW+FILTER (solo herramientas autorizadas), o
  • DENY total cuando el agente usa catálogo preconfigurado.

6) Implementación técnica (PEP determinista)

6.1 Algoritmo de decisión

verify_signature_and_standard_claims(token)
resource_id = canonicalize(request.host, request.basePath)

if !aud_contains(token.aud, resource_id):
    deny(401, invalid_token)

tool_name = request.json.params.name
if !valid_tool_name(tool_name):
    deny(400, invalid_request)

allowed = permissions_from(token.scope, token.tool_permissions)
if !allows(allowed, resource_id, tool_name):
    deny(403, insufficient_scope)

allow_forward()

6.2 Canonicalización (evitar bypass)

  • Recurso: normalizar scheme/host/port/path según contrato único.
  • Herramienta: respetar política de case-sensitivity definida; si se impone lowercase, documentarlo y denegar variantes.
  • Claims: rechazar dualidad conflictiva (scope dice ALLOW, tool_permissions dice DENY o viceversa).

6.3 Códigos de error sugeridos

  • 401 invalid_token: firma/exp/iss/aud inválidos.
  • 403 insufficient_scope: tool no permitida.
  • 400 invalid_request: JSON-RPC mal formado o params.name inválido.

6.4 Telemetría mínima

Por cada tools/call registrar:

  • iss, sub, client_id, jti (si existe), intent_id.
  • resource_id canónico evaluado.
  • params.name.
  • decisión y motivo (aud_mismatch, tool_denied, etc.).
  • latencia de verificación.

7) Checklist de implementación

Política y diseño

  • [ ] Catálogo de tools clasificado por riesgo (R/O, write, irreversible, admin).
  • [ ] Convención de nombres de herramienta única y documentada.
  • [ ] Fuente de verdad única para permisos (scope vs claim estructurado).

Emisión de token (PDP)

  • [ ] resource RFC 8707 usado explícitamente para tokens MCP.
  • [ ] aud emitido en forma canónica y verificable.
  • [ ] Downscope por intención en token exchange (sin ampliación lateral).
  • [ ] TTL corto para tokens downstream.

Enforcement (PEP)

  • [ ] Validación JWT completa antes de tools/call.
  • [ ] Validación aud por membresía exacta (string/array).
  • [ ] Match exacto de params.name contra permisos.
  • [ ] Fail-closed ante ambigüedad o claims inválidos.
  • [ ] tools/list filtrado o denegado.

Hardening

  • [ ] Evaluado DPoP/mTLS para reducir replay.
  • [ ] Prohibido bearer token en query string.
  • [ ] Alerta por picos de denegación en tools críticas.

Pruebas de conformidad

  • [ ] ALLOW: aud correcta + tool permitida.
  • [ ] DENY: aud correcta + tool no permitida.
  • [ ] DENY: aud incorrecta + tool permitida.
  • [ ] DENY: intento de escalada en token exchange.
  • [ ] Replay simulation (sin y con sender-constraint).

8) Referencias

  1. RFC 9700 — OAuth 2.0 Security BCP: https://datatracker.ietf.org/doc/rfc9700/
  2. RFC 8707 — Resource Indicators: https://www.rfc-editor.org/rfc/rfc8707
  3. RFC 8693 — OAuth 2.0 Token Exchange: https://www.rfc-editor.org/rfc/rfc8693
  4. RFC 9068 — JWT Profile for OAuth 2.0 Access Tokens: https://www.rfc-editor.org/rfc/rfc9068
  5. RFC 7519 — JWT: https://www.rfc-editor.org/rfc/rfc7519
  6. RFC 6749 §3.3 — Scope syntax: https://www.rfc-editor.org/rfc/rfc6749#section-3.3
  7. RFC 9449 — DPoP: https://www.rfc-editor.org/rfc/rfc9449
  8. RFC 9728 — Protected Resource Metadata: https://datatracker.ietf.org/doc/rfc9728/
  9. RFC 9396 — Rich Authorization Requests: https://datatracker.ietf.org/doc/html/rfc9396
  10. MCP Spec 2025-11-25 (tools): https://modelcontextprotocol.io/specification/2025-11-25/server/tools
  11. MCP Spec 2025-11-25 (authorization): https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization
  12. Keycloak 26.4 release notes: https://www.keycloak.org/2025/09/keycloak-2640-released
  13. Keycloak MCP authz server guide: https://www.keycloak.org/securing-apps/mcp-authz-server

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.