Kubernetes-MCP-Guard
Plan de aprobación seguro para IA que controla operaciones de Kubernetes mediante MCP con OAuth, RBAC, auditoría y protecciones.
Documentación
🛡️ Kubernetes MCP Guard
Remediación de Kubernetes impulsada por IA, aprobada por humanos, a través de una puerta de enlace MCP protegida.
Remediación, por diseño:
El Observador detecta anomalías.
El Planificador propone un plan respaldado por evidencia.
El revisor humano aprueba fuera de banda.
El Ejecutor solo ejecuta el plan aprobado vinculado a un digest.
Todo es auditable.
📝 Resumen
Cuando algo falla, el sistema puede recopilar evidencia, proponer una corrección acotada, probarla en seco, empaquetarla en un plan revisable y esperar la aprobación humana.
Es un puente de seguridad primero entre los agentes de IA y Kubernetes, con aprobación fuera de banda, autenticada con OAuth, con intervención humana (HITL) y basada en planes para cada mutación expuesta por la puerta de enlace.
¿Por qué?
Los agentes de IA pueden ayudar a diagnosticar problemas de infraestructura, pero darles acceso directo a mutaciones es arriesgado. Kubernetes MCP Guard explora un patrón más seguro: los agentes pueden observar, probar en seco y proponer remediaciones acotadas, mientras que los humanos aprueban el plan exacto vinculado a un digest antes de que ocurra cualquier escritura en Kubernetes.
🎬 Demostración
https://github.com/user-attachments/assets/4e06b4ee-db80-4d74-96cc-38dfbb413042
[!NOTA] Escenario de demostración:
- Un Deployment se rompe intencionalmente.
- El Observador detecta la carga de trabajo no saludable.
- El Planificador propone una remediación acotada.
- Se envía un código de acceso de aprobación por correo electrónico al operador configurado.
- Un humano autenticado aprueba el plan exacto en el navegador.
- El Ejecutor aplica la mutación aprobada.
El recorrido en docs/demo-failing-deployment.md muestra el flujo completo contra un Deployment deliberadamente roto.
🧠 Ideas Centrales
Kubernetes MCP Guard explora un patrón práctico de seguridad para operaciones asistidas por IA:
- Planificar antes de mutar: cada escritura expuesta por la puerta de enlace comienza como un plan
request_*construido a partir de evidencia de prueba en seco del lado del servidor de Kubernetes. - Canal de revisión separado: el cliente MCP recibe una URL de aprobación, mientras que la aprobación ocurre a través de
/approvals/*en una sesión OAuth del navegador. - Aprobación vinculada a digest: la ejecución está vinculada a un Digest de Intención para la mutación ejecutable y un Digest de Revisión para la instantánea revisada por humanos.
- Modelo de concesión duradera: un Desafío de Aprobación aprobado registra un Resultado de Desafío y emite una Concesión de Aprobación consumida por las compuertas previas a la ejecución.
- Alcance reducido de Kubernetes: listas de permitidos de namespaces, RBAC limitado a namespaces, verificaciones de tipos admitidos y herramientas de lectura acotadas mantienen la superficie operativa pequeña.
- Controles auditables: los eventos de protección y aprobación se escriben como flujos JSONL con identidad, digest, concesión y contexto de ejecución.
- Coordinación multiagente estructurada: Observador, Planificador y Ejecutor son procesos independientes (agentes) que se comunican a través del protocolo A2A (vía
a2a-dotnet), cada uno con una identidad de servicio OAuth separada y un alcance de puerta de enlace reducido. El Planificador posee una Tarea duradera por anomalía que persiste entre reinicios y aplica una remediación por anomalía sin bloqueo entre servicios.
El repositorio también separa el ciclo de vida genérico de aprobación del adaptador de Kubernetes, de modo que el lenguaje central no esté vinculado a un único dominio de infraestructura.
Ver CONTEXT.md, docs/mutation-approval-profile.md, docs/mutation-approval-flow.md.
🗺️ Arquitectura
---
title: Security Boundaries
---
flowchart TB
subgraph outer["🌐 Internet / Operator"]
Human["👤 Operator\nbrowser · OAuth PKCE"]
McpClient["🤖 MCP Client\nCodex · Claude Code"]
end
subgraph gateway["🛡️ Gateway — OAuth JWT required"]
direction LR
Guard["🔍 Guardrails\n+ ToolScopeGuard"]
ApprovalUI["📋 Approval UI\n/approvals/*"]
ApprovalCore["🔐 Approval Core\nplan · challenge · grant · digest"]
end
subgraph agents["🤖 Agent Tier — client_credentials · narrow scopes"]
direction LR
Obs["🔎 Observer\nmcp:tools.readonly"]
Plan["📋 Planner\nmcp:tools.propose + readonly"]
Exec["🛠️ Executor\nmcp:tools.execute"]
Obs <-->|"A2A"| Plan <-->|"A2A"| Exec
end
subgraph private["🔒 Private Subprocess — no public port"]
McpServer["⚙️ McpServer\nKubernetes tools"]
end
K8s(("☸️ Kubernetes API\n(namespace-scoped RBAC)"))
Human -->|"review snapshot · approve/deny"| ApprovalUI --> ApprovalCore
McpClient -->|"Bearer JWT · mcp:tools.read/write"| Guard -->|"scope-filtered tool call"| ApprovalCore
agents -->|"Bearer JWT · service identity"| Guard
ApprovalCore -->|"stdio · service token"| McpServer -->|"KubernetesClient"| K8s
El Observador notifica al Planificador y el Planificador despacha al Ejecutor de forma síncrona y espera el resultado.
El pipeline interno de remediación del Planificador es un DAG concurrente construido sobre Microsoft.Agents.AI.Workflows, distribuyendo cada anomalía entrante a través de Filter → Dedupe → LLM-Decide → Validate → Propose executor chains independientes.
Los diagramas completos del flujo de solicitudes están en docs/architecture.md.
🔐 Flujo de Aprobación
La propiedad de seguridad central es que la aprobación es necesaria pero no suficiente. Una aprobación humana crea autorización de ejecución, pero la ejecución aún debe pasar las compuertas previas a la ejecución inmediatamente antes de mutar Kubernetes.
| Fase | Qué sucede | Qué puede bloquearla |
|---|---|---|
| Planificar | Un cliente MCP impulsado por humanos llama a request_*, o el Planificador llama a propose_plan; el adaptador de Kubernetes recopila evidencia de prueba en seco, diff y políticas; el núcleo genérico almacena un Sobre de Plan con Digests de Intención y Revisión. | Rechazo de namespace, rechazo de lista de permitidos de manifiestos, fallo de prueba en seco, denegación de política de dominio, formato de plan heredado no compatible. |
| Aprobar | El cliente llama a execute_approved_plan; la puerta de enlace crea o reutiliza un Desafío de Aprobación de corta duración y devuelve una URL de navegador. El navegador renderiza la instantánea de revisión almacenada, no el texto de aprobación proporcionado por el modelo. | Desafío expirado, sujeto autenticado incorrecto, fallo anti-falsificación, vinculación de digest cambiada, Resultado de Desafío denegado/rechazado/cancelado. |
| Ejecutar | Después de la aprobación, el cliente reintenta execute_approved_plan; la puerta de enlace valida la Concesión de Aprobación, los digests, la ventana de validez, la política de reutilización, las verificaciones de frescura y las verificaciones de política de dominio antes de que el adaptador escriba. | Concesión faltante/expirada/no coincidente, discrepancia de digest, Plan de Ejecución Única ya aplicado, segundo fallo de prueba en seco, fallo de política, desviación del estado en vivo. |
Las notas de implementación actuales se rastrean en docs/mutation-approval-profile.md#current-repository-fit.
🧰 Capacidades Actuales
🤖🔎 Observador de Anomalías
El InfraGate.Observer es un agente impulsado por LLM que inspecciona periódicamente el clúster a través de las herramientas de solo lectura de la puerta de enlace y emite Informes de Anomalías estructurados.
| Capacidad | Descripción |
|---|---|
| Observación programada | El IHostedService en segundo plano ejecuta ciclos en una cadencia configurable (predeterminado 60s). |
| Disparo bajo demanda | POST /observe-now devuelve un AnomalyReport[] síncrono con un tiempo de espera de 30s. |
| Detección de anomalías | Clasificación asistida por LLM en cuatro categorías: Pod no saludable, Deployment no disponible, Service sin endpoints, Eventos de advertencia. |
| Clasificación de severidad | High/Medium/Low derivados de reglas con telemetría de desacuerdo del LLM. |
| Deduplicación y resolución | La ventana de deduplicación en memoria suprime informes repetidos; emisión automática de Resolved cuando las anomalías se resuelven. |
| Transferencia | El sumidero de registros siempre está activo; el sumidero de archivos JSON y la transferencia A2A del Planificador son opcionales; ver docs/configuration.md. |
🤖📋 Planificador de Remediación
El InfraGate.Planner consume Informes de Anomalías, elige una operación de remediación acotada y crea planes de Política de Aprobación de Operador pendientes de aprobación a través de propose_plan.
| Capacidad | Descripción |
|---|---|
| Recepción de anomalías | Recibe cargas útiles de AnomalyHandoffBatch del Observador a través de A2A; cada anomalía se procesa de forma independiente a través de un pipeline DAG concurrente: Filtrar → Deduplicar → Decidir-LLM → Validar → Proponer. |
| Menú de operaciones | Elige solo restart_deployment, scale_deployment o set_deployment_image en v1. |
| Propuesta de plan | Llama a propose_plan para crear un Sobre de Plan vinculado a digest para aprobación del operador. |
| Notificación de aprobación | propose_plan crea un Código de Acceso de Aprobación y envía el correo electrónico del operador configurado a través del remitente SMTP de la puerta de enlace cuando está configurado. |
| Ciclo de vida de tarea duradera | Una Tarea A2A por anomalía (clave por contextId) rastrea el estado desde Submitted a través de Working, AuthRequired (esperando aprobación del operador), hasta Completed/Failed/Rejected. Persistida en PostgreSQL cuando InfraGate__Planner__AuditConnectionString está configurado; de lo contrario, en memoria. |
| Límite de alcance | El Planificador puede proponer planes y usar herramientas de inspección de solo lectura; no puede ejecutar planes. |
🤖🛠️ Ejecutor de Remediación
El InfraGate.Executor consume propuestas del Planificador, espera la aprobación y ejecuta solo después de que la puerta de enlace informe que existe una Concesión de Aprobación.
| Capacidad | Descripción |
|---|---|
| Recepción de propuestas | Recibe ids de planes del Planificador a través de despacho A2A síncrono. |
| Espera de aprobación | Llama a wait_for_plan_approval para cada id de plan hasta aprobación, tiempo de espera o estado terminal. |
| Ejecución aprobada | Llama a execute_approved_plan solo después de que se informe la aprobación. |
| Límite de alcance | El Ejecutor puede esperar y ejecutar planes aprobados; no puede crear planes ni llamar a herramientas de inspección de solo lectura. |
| Compuertas de puerta de enlace | La puerta de enlace aún aplica concesiones de aprobación, digests, frescura, verificaciones de políticas y ejecución única. |
🛡️ Protecciones de la Puerta de Enlace
| Capa | Comportamiento actual |
|---|---|
| Transporte MCP | Endpoint MCP HTTP en /mcp usando Streamable HTTP. |
| Autenticación | Validación de JWT OAuth para llamadas MCP; cookie OAuth del navegador para páginas de aprobación. |
| Descubrimiento OAuth | Metadatos de recursos protegidos y desafíos de alcance insuficiente para clientes MCP. |
| Autoridad de aprobación | Endpoints de aprobación del navegador bajo /approvals/* con vinculación del mismo sujeto y verificaciones anti-falsificación. |
| Protecciones | Advertir sobre patrones de solicitud sospechosos y redactar contenido de respuesta sospechoso antes de que regrese al cliente MCP. |
| Auditoría | Flujos JSONL separados para hallazgos de protección y eventos del ciclo de vida de aprobación. |
🔎 Observabilidad de Solo Lectura
| Herramienta | Propósito |
|---|---|
get_allowed_namespaces | Devuelve la lista de permitidos de namespaces configurada para el servidor. |
get_k8s_status | Resume Deployments, Services, ConfigMaps, Pods y ReplicaSets en un namespace. |
get_k8s_events | Lee diagnósticos acotados de events.k8s.io/v1. |
get_pod_logs | Lee registros de Pod acotados con límites de líneas de cola y bytes. |
get_k8s_resource | Devuelve un resumen de recursos enfocado sin valores de Secret, datos de ConfigMap ni manifiestos sin procesar. |
get_deployment_diagnostics | Inspecciona la salud del Deployment, Pods relacionados, ReplicaSets y Eventos. |
get_pod_diagnostics | Inspecciona el estado del Pod, condiciones, estado del contenedor y Eventos. |
get_service_diagnostics | Inspecciona endpoints de Service, Pods de respaldo y Eventos. |
✅ Herramientas de Aprobación de la Puerta de Enlace
| Herramienta | Propósito |
|---|---|
request_apply_manifest | Prueba en seco y planifica la aplicación del lado del servidor para Deployment, Service o ConfigMap. |
request_delete_manifest | Prueba en seco y planifica la eliminación para tipos de manifiesto admitidos. |
request_scale_deployment | Prueba en seco y planifica un cambio en el número de réplicas de un Deployment. |
request_restart_deployment | Prueba en seco y planifica un reinicio de implementación de un Deployment. |
request_set_deployment_image | Prueba en seco y planifica una actualización de imagen de contenedor de un Deployment. |
propose_plan | Crea un plan de Política de Aprobación de Operador pendiente de aprobación para el menú de operaciones del Planificador autónomo. |
execute_approved_plan | Crea el desafío de aprobación del navegador o ejecuta un plan aprobado vinculado a digest después de que pasen las compuertas. |
get_plan_status | Lee el estado de aprobación actual de un plan. |
wait_for_plan_approval | Espera brevemente una aprobación del navegador fuera de banda y devuelve JSON de estado sin aplicar el plan. |
Las herramientas directas de mutación de Kubernetes existen dentro de la superficie privada del servidor para el ejecutor del adaptador. La puerta de enlace HTTP expone envoltorios request_* más execute_approved_plan en lugar de exponer herramientas destructivas sin procesar a los clientes MCP.
⚡ Inicio Rápido
Requisitos previos: Docker Compose v2, kubectl, minikube y git.
Revise docs/configuration.md antes de cambiar la configuración de tiempo de ejecución.
📦 Desde Paquetes
El inicio rápido predeterminado usa imágenes publicadas y valores predeterminados de demostración local confirmados.
git clone https://github.com/mirusser/Kubernetes-MCP-Guard.git
cd Kubernetes-MCP-Guard
export InfraGate__OpenRouter__ApiKey="<openrouter-api-key>"
make quickstart
make quickstart inicia la ruta OAuth local respaldada por Keycloak, el almacén de aprobaciones PostgreSQL y la imagen de puerta de enlace publicada con TAG=latest. Fija una versión con TAG=v0.1.0 make quickstart. Los valores predeterminados confirmados sin SDK provienen del perfil de ejecución smoke-release: deploy/local-oauth/release.env.example proporciona tanto la interpolación de Compose como la configuración de tiempo de ejecución de InfraGate__....
🛠️ Desde el código fuente
Usa el modo de código fuente cuando quieras que la puerta de enlace, Observer, Planner y Executor se compilen desde el código local. Esta ruta requiere el .NET 10 SDK y una clave de API de OpenRouter para los agentes basados en LLM. La compilación de Docker obtiene el downstream secundario opcional de solo lectura kubernetes-mcp-server desde su versión oficial, verificado por checksum contra scripts/kubernetes-mcp-server.manifest.json; ejecuta ./scripts/install-kubernetes-mcp-server.sh (necesita curl, sha256sum, jq) en el host solo cuando ejecutes ese downstream o su prueba de integración en vivo directamente.
export InfraGate__OpenRouter__ApiKey="<openrouter-api-key>"
make quickstart-source
El inicio rápido desde el código fuente genera deploy/generated/local-compose.env (configuración predeterminada) a partir de deploy/run-profiles.yaml e inicia la puerta de enlace, Observer, Planner y Executor desde compilaciones de código fuente local.
Comandos de seguimiento útiles:
make quickstart-logs
make quickstart-down
Otros modos de ejecución y detalles completos de configuración están en docs/setup-guide.md.
⌨️ Conectar Codex CLI
Agrega esto a ~/.codex/config.toml:
[mcp_servers.infra-gate]
url = "http://127.0.0.1:3001/mcp"
oauth_resource = "http://127.0.0.1:3001/mcp"
scopes = ["mcp:tools.read"]
Usa mcp:tools.write para sesiones donde planees crear y aplicar planes de mutación. El alcance heredado mcp:tools otorga acceso completo para compatibilidad hacia atrás.
Luego autentícate e inicia Codex:
codex mcp login infra-gate
codex
💬 Conectar Claude Code
claude mcp add-json --scope user infra-gate \
'{"type":"http","url":"http://127.0.0.1:3001/mcp","oauth":{"scopes":"mcp:tools.read"}}'
claude
/mcp
📦 Imágenes de contenedor
Las imágenes de versión se compilan mediante el flujo de trabajo de Docker y se publican en GHCR y Docker Hub.
| Registro | Imagen de puerta de enlace |
|---|---|
| GitHub Container Registry | ghcr.io/mirusser/kubernetes-mcp-guard-gateway:<tag> |
| Docker Hub | mirusser/kubernetes-mcp-guard-gateway:<tag> |
Usa etiquetas de versión específicas para demos estables. La etiqueta :dev sigue la rama de desarrollo, y :latest sigue la versión estable más reciente.
🧩 Compatibilidad
| Área | Compatible / probado |
|---|---|
| .NET | .NET 10 |
| Kubernetes | minikube / clúster local inicialmente |
| Transporte MCP | Endpoint MCP HTTP en /mcp |
| OIDC | Ruta local/de desarrollo de Keycloak; proveedores OIDC externos por configuración |
| Registros de contenedores | GHCR, Docker Hub |
| Plataformas | linux/amd64 inicialmente |
🧭 Mapa del proyecto
- Runbook para desarrolladores, ejecuciones locales, contratos de herramientas MCP y verificación: docs/devs-readme.md.
- Rutas de configuración, perfiles de ejecución, variables de entorno y guía de producción: docs/setup-guide.md y docs/configuration.md.
- docs/architecture.md, docs/security-model.md, docs/tool-permissions.md: flujos de solicitudes, límites de seguridad y permisos por herramienta.
- docs/observability-model.md: señales de telemetría, ruta de correlación de eventos de auditoría, el Aspire Dashboard solo para desarrollo y el navegador de línea de tiempo de auditoría (
/audit/timeline/{planId}). - Servicios de tiempo de ejecución: McpGateway, McpServer, Observer, Planner y Executor.
- Dominio de aprobaciones y Kubernetes: Approvals, Approvals.Postgres y KubernetesAdapter.
- Validación y demos: tests, ejemplo de implementación fallida y SonarQube local.
⚖️ Límites y no objetivos
[!IMPORTANT]
- El proyecto es experimental y no está certificado para producción.
- El realm local de Keycloak se ejecuta en modo de desarrollo sobre HTTP y no es un proveedor de identidad de producción.
- Las salvaguardas contra inyección de prompts son defensa en profundidad, no un límite de seguridad duro garantizado.
- La superficie de herramientas no expone ejecución de shell, paso a través de
kubectl, exec, attach, port-forward, creación de namespaces, manipulación de RBAC, lecturas de Secretos, lecturas de manifiestos sin procesar ni escrituras a nivel de clúster.- Esto no es un motor de políticas completo de Kubernetes ni un estándar MCP.
Consulta docs/security-model.md para el modelo de amenazas completo.
Es una implementación de referencia funcional para un posible perfil de aprobación de mutaciones MCP, diseñada para evaluación técnica temprana en entornos locales o estrictamente controlados, no infraestructura certificada para producción.
El código base usa InfraGate como nombre interno del proyecto.
📜 Gobernanza
- Licencia: Apache-2.0
- Política de seguridad: SECURITY.md
- Guía de contribución: CONTRIBUTING.md
- Registro de cambios: CHANGELOG.md
- Proceso de versiones: docs/releasing.md
Hecho con ❤️, ☕ y pequeños guardarraíles cuidadosos 🛡️✨