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.


Unit Tests Integration Tests Docker Quality Gate Status Coverage Badge Hi Mom

.NET 10 Kubernetes Docker MCP AI Agents

📝 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:

  1. Un Deployment se rompe intencionalmente.
  2. El Observador detecta la carga de trabajo no saludable.
  3. El Planificador propone una remediación acotada.
  4. Se envía un código de acceso de aprobación por correo electrónico al operador configurado.
  5. Un humano autenticado aprueba el plan exacto en el navegador.
  6. 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.

FaseQué sucedeQué puede bloquearla
PlanificarUn 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.
AprobarEl 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.
EjecutarDespué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.

CapacidadDescripción
Observación programadaEl IHostedService en segundo plano ejecuta ciclos en una cadencia configurable (predeterminado 60s).
Disparo bajo demandaPOST /observe-now devuelve un AnomalyReport[] síncrono con un tiempo de espera de 30s.
Detección de anomalíasClasificación asistida por LLM en cuatro categorías: Pod no saludable, Deployment no disponible, Service sin endpoints, Eventos de advertencia.
Clasificación de severidadHigh/Medium/Low derivados de reglas con telemetría de desacuerdo del LLM.
Deduplicación y resoluciónLa ventana de deduplicación en memoria suprime informes repetidos; emisión automática de Resolved cuando las anomalías se resuelven.
TransferenciaEl 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.

CapacidadDescripción
Recepción de anomalíasRecibe 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 operacionesElige solo restart_deployment, scale_deployment o set_deployment_image en v1.
Propuesta de planLlama a propose_plan para crear un Sobre de Plan vinculado a digest para aprobación del operador.
Notificación de aprobaciónpropose_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 duraderaUna 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 alcanceEl 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.

CapacidadDescripción
Recepción de propuestasRecibe ids de planes del Planificador a través de despacho A2A síncrono.
Espera de aprobaciónLlama a wait_for_plan_approval para cada id de plan hasta aprobación, tiempo de espera o estado terminal.
Ejecución aprobadaLlama a execute_approved_plan solo después de que se informe la aprobación.
Límite de alcanceEl 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 enlaceLa 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

CapaComportamiento actual
Transporte MCPEndpoint MCP HTTP en /mcp usando Streamable HTTP.
AutenticaciónValidación de JWT OAuth para llamadas MCP; cookie OAuth del navegador para páginas de aprobación.
Descubrimiento OAuthMetadatos de recursos protegidos y desafíos de alcance insuficiente para clientes MCP.
Autoridad de aprobaciónEndpoints de aprobación del navegador bajo /approvals/* con vinculación del mismo sujeto y verificaciones anti-falsificación.
ProteccionesAdvertir sobre patrones de solicitud sospechosos y redactar contenido de respuesta sospechoso antes de que regrese al cliente MCP.
AuditoríaFlujos JSONL separados para hallazgos de protección y eventos del ciclo de vida de aprobación.

🔎 Observabilidad de Solo Lectura

HerramientaPropósito
get_allowed_namespacesDevuelve la lista de permitidos de namespaces configurada para el servidor.
get_k8s_statusResume Deployments, Services, ConfigMaps, Pods y ReplicaSets en un namespace.
get_k8s_eventsLee diagnósticos acotados de events.k8s.io/v1.
get_pod_logsLee registros de Pod acotados con límites de líneas de cola y bytes.
get_k8s_resourceDevuelve un resumen de recursos enfocado sin valores de Secret, datos de ConfigMap ni manifiestos sin procesar.
get_deployment_diagnosticsInspecciona la salud del Deployment, Pods relacionados, ReplicaSets y Eventos.
get_pod_diagnosticsInspecciona el estado del Pod, condiciones, estado del contenedor y Eventos.
get_service_diagnosticsInspecciona endpoints de Service, Pods de respaldo y Eventos.

✅ Herramientas de Aprobación de la Puerta de Enlace

HerramientaPropósito
request_apply_manifestPrueba en seco y planifica la aplicación del lado del servidor para Deployment, Service o ConfigMap.
request_delete_manifestPrueba en seco y planifica la eliminación para tipos de manifiesto admitidos.
request_scale_deploymentPrueba en seco y planifica un cambio en el número de réplicas de un Deployment.
request_restart_deploymentPrueba en seco y planifica un reinicio de implementación de un Deployment.
request_set_deployment_imagePrueba en seco y planifica una actualización de imagen de contenedor de un Deployment.
propose_planCrea 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_planCrea 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_statusLee el estado de aprobación actual de un plan.
wait_for_plan_approvalEspera 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.

RegistroImagen de puerta de enlace
GitHub Container Registryghcr.io/mirusser/kubernetes-mcp-guard-gateway:<tag>
Docker Hubmirusser/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

ÁreaCompatible / probado
.NET.NET 10
Kubernetesminikube / clúster local inicialmente
Transporte MCPEndpoint MCP HTTP en /mcp
OIDCRuta local/de desarrollo de Keycloak; proveedores OIDC externos por configuración
Registros de contenedoresGHCR, Docker Hub
Plataformaslinux/amd64 inicialmente

🧭 Mapa del proyecto

⚖️ 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


Hecho con ❤️, ☕ y pequeños guardarraíles cuidadosos 🛡️✨