Kubernetes-MCP-Guard
Plano de aprovação seguro por IA para operações Kubernetes controladas via MCP com OAuth, RBAC, auditoria e proteções.
Documentação
🛡️ Kubernetes MCP Guard
Remediação orientada por IA e aprovada por humanos através de um gateway MCP protegido.
Remediação, por design:
O Observador detecta anomalias.
O Planejador propõe um plano baseado em evidências.
O Revisor humano aprova fora do canal.
O Executor executa apenas o plano aprovado e vinculado ao digest.
Tudo é auditável.
📝 Resumo
Quando algo quebra, o sistema pode coletar evidências, propor uma correção limitada, executar um dry-run, empacotá-la em um plano revisável e aguardar a aprovação humana.
É uma ponte security-first entre agentes de IA e Kubernetes, com aprovação baseada em planos, fora do canal, autenticada via OAuth e com humano no circuito (HITL) para cada mutação exposta pelo gateway.
Por quê?
Agentes de IA podem ajudar a diagnosticar problemas de infraestrutura, mas dar a eles acesso direto a mutações é arriscado. O Kubernetes MCP Guard explora um padrão mais seguro: os agentes podem observar, executar dry-run e propor remediações limitadas, enquanto os humanos aprovam o plano exato vinculado ao digest antes de qualquer escrita no Kubernetes ocorrer.
🎬 Demonstração
https://github.com/user-attachments/assets/4e06b4ee-db80-4d74-96cc-38dfbb413042
[!NOTE] Cenário da demonstração:
- Um Deployment é quebrado intencionalmente.
- O Observador detecta a carga de trabalho não saudável.
- O Planejador propõe uma remediação limitada.
- Um código de acesso de aprovação é enviado por e-mail ao operador configurado.
- Um humano autenticado aprova o plano exato no navegador.
- O Executor aplica a mutação aprovada.
O passo a passo em docs/demo-failing-deployment.md mostra o fluxo completo contra um Deployment deliberadamente quebrado.
🧠 Ideias Centrais
O Kubernetes MCP Guard explora um padrão prático de segurança para operações assistidas por IA:
- Planeje antes de mutar: toda escrita exposta pelo gateway começa como um plano
request_*construído a partir de evidências de dry-run do lado do servidor Kubernetes. - Canal de revisão separado: o cliente MCP recebe uma URL de aprovação, enquanto a aprovação acontece através do
/approvals/*em uma sessão OAuth no navegador. - Aprovação vinculada ao digest: a execução é vinculada a um Intent Digest para a mutação executável e a um Review Digest para o snapshot revisado por humanos.
- Modelo de concessão durável: um Approval Challenge aprovado registra um Challenge Outcome e emite um Approval Grant consumido pelas verificações pré-execução.
- Escopo Kubernetes restrito: allow-lists de namespaces, RBAC com escopo de namespace, verificações de tipos suportados e ferramentas de leitura limitadas mantêm a superfície operacional pequena.
- Controles auditáveis: eventos de guardrail e aprovação são gravados como streams JSONL com identidade, digest, concessão e contexto de execução.
- Coordenação multiagente estruturada: Observador, Planejador e Executor são processos independentes (agentes) que se comunicam através do protocolo A2A (via
a2a-dotnet), cada um com uma identidade de serviço OAuth separada e um escopo de gateway restrito. O Planejador possui uma Task durável por anomalia que persiste entre reinicializações e impõe uma remediação por anomalia sem bloqueio entre serviços.
O repositório também separa o ciclo de vida genérico de aprovação do adaptador Kubernetes, para que a linguagem central não esteja vinculada a um único domínio de infraestrutura.
Veja CONTEXT.md, docs/mutation-approval-profile.md, docs/mutation-approval-flow.md.
🗺️ Arquitetura
---
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
O Observador notifica o Planejador, e o Planejador despacha para o Executor de forma síncrona e aguarda o resultado.
O pipeline interno de remediação do Planejador é um DAG concorrente construído sobre Microsoft.Agents.AI.Workflows, distribuindo cada anomalia recebida através de Filter → Dedupe → LLM-Decide → Validate → Propose executor chains independentes.
Diagramas completos do fluxo de requisições estão em docs/architecture.md.
🔐 Fluxo de Aprovação
A propriedade central de segurança é que a aprovação é necessária, mas não suficiente. Uma aprovação humana cria autorização de execução, mas a execução ainda precisa passar pelas verificações pré-execução imediatamente antes de o Kubernetes ser mutado.
| Fase | O que acontece | O que pode bloqueá-la |
|---|---|---|
| Planejar | Um cliente MCP conduzido por humano chama request_*, ou o Planejador chama propose_plan; o adaptador Kubernetes coleta evidências de dry-run, diff e política; o núcleo genérico armazena um Plan Envelope com Intent e Review Digests. | Rejeição de namespace, rejeição da allow-list de manifestos, falha no dry-run, negação de política de domínio, formato de plano legado não suportado. |
| Aprovar | O cliente chama execute_approved_plan; o gateway cria ou reutiliza um Approval Challenge de curta duração e retorna uma URL de navegador. O navegador renderiza o snapshot de revisão armazenado, não o texto de aprovação fornecido pelo modelo. | Challenge expirado, sujeito autenticado incorreto, falha anti-falsificação, vinculação de digest alterada, Challenge Outcome negado/rejeitado/cancelado. |
| Executar | Após a aprovação, o cliente tenta novamente execute_approved_plan; o gateway valida o Approval Grant, digests, janela de validade, política de reutilização, verificações de atualização e verificações de política de domínio antes de o adaptador escrever. | Grant ausente/expirado/incompatível, digest incompatível, Single-Execution Plan já aplicado, segunda falha no dry-run, falha de política, desvio de estado ativo. |
As notas de implementação atuais são rastreadas em docs/mutation-approval-profile.md#current-repository-fit.
🧰 Capacidades Atuais
🤖🔎 Observador de Anomalias
O InfraGate.Observer é um agente orientado por LLM que inspeciona periodicamente o cluster através das ferramentas somente leitura do gateway e emite Relatórios de Anomalias estruturados.
| Capacidade | Descrição |
|---|---|
| Observação agendada | O IHostedService em segundo plano executa ciclos em uma cadência configurável (padrão 60s). |
| Acionamento sob demanda | POST /observe-now retorna um AnomalyReport[] síncrono com timeout de 30s. |
| Detecção de anomalias | Classificação assistida por LLM em quatro categorias: Pod não saudável, Deployment indisponível, Service sem endpoints, Eventos de aviso. |
| Classificação de severidade | High/Medium/Low derivados de regras com telemetria de discordância do LLM. |
| Deduplicação e resolução | Janela de deduplicação em memória suprime relatórios repetidos; emissão automática de Resolved quando as anomalias são resolvidas. |
| Encaminhamento | Sink de log sempre ativo; sink de arquivo JSON e encaminhamento A2A para o Planejador são opcionais; veja docs/configuration.md. |
🤖📋 Planejador de Remediação
O InfraGate.Planner consome Relatórios de Anomalias, escolhe uma operação de remediação limitada e cria planos Operator Approval Policy pendentes de aprovação através de propose_plan.
| Capacidade | Descrição |
|---|---|
| Recebimento de anomalias | Recebe payloads de AnomalyHandoffBatch do Observador via A2A; cada anomalia é processada independentemente através de um pipeline DAG concorrente: Filter → Dedupe → LLM-Decide → Validate → Propose. |
| Menu de operações | Escolhe apenas restart_deployment, scale_deployment ou set_deployment_image na v1. |
| Proposta de plano | Chama propose_plan para criar um Plan Envelope vinculado ao digest para aprovação do operador. |
| Notificação de aprovação | propose_plan cria um Approval Access Code e envia o e-mail do operador configurado através do remetente SMTP do gateway quando configurado. |
| Ciclo de vida durável da task | Uma A2A Task por anomalia (chaveada por contextId) rastreia o estado de Submitted até Working, AuthRequired (aguardando aprovação do operador), até Completed/Failed/Rejected. Persistida no PostgreSQL quando InfraGate__Planner__AuditConnectionString está definido; caso contrário, em memória. |
| Limite de escopo | O Planejador pode propor planos e usar ferramentas de inspeção somente leitura; não pode executar planos. |
🤖🛠️ Executor de Remediação
O InfraGate.Executor consome propostas do Planejador, aguarda aprovação e executa somente após o gateway relatar que um Approval Grant existe.
| Capacidade | Descrição |
|---|---|
| Recebimento de propostas | Recebe ids de planos do Planejador via despacho A2A síncrono. |
| Aguardo de aprovação | Chama wait_for_plan_approval para cada id de plano até aprovação, timeout ou status terminal. |
| Execução aprovada | Chama execute_approved_plan somente após a aprovação ser relatada. |
| Limite de escopo | O Executor pode aguardar e executar planos aprovados; não pode criar planos ou chamar ferramentas de inspeção somente leitura. |
| Verificações do gateway | O gateway ainda impõe grants de aprovação, digests, atualização, verificações de política e execução única. |
🛡️ Proteções do Gateway
| Camada | Comportamento atual |
|---|---|
| Transporte MCP | Endpoint MCP HTTP em /mcp usando Streamable HTTP. |
| Autenticação | Validação de JWT OAuth para chamadas MCP; cookie OAuth de navegador para páginas de aprovação. |
| Descoberta OAuth | Metadados de recurso protegido e desafios de escopo insuficiente para clientes MCP. |
| Autoridade de aprovação | Endpoints de aprovação no navegador sob /approvals/* com vinculação de mesmo sujeito e verificações anti-falsificação. |
| Guardrails | Avisa sobre padrões de requisição suspeitos e redige conteúdo de resposta suspeito antes de retorná-lo ao cliente MCP. |
| Auditoria | Streams JSONL separados para descobertas de guardrail e eventos do ciclo de vida de aprovação. |
🔎 Observabilidade Somente Leitura
| Ferramenta | Propósito |
|---|---|
get_allowed_namespaces | Retorna a allow-list de namespaces configurada para o servidor. |
get_k8s_status | Resume Deployments, Services, ConfigMaps, Pods e ReplicaSets em um namespace. |
get_k8s_events | Lê diagnósticos limitados de events.k8s.io/v1. |
get_pod_logs | Lê logs de Pod limitados com limites de linhas finais e bytes. |
get_k8s_resource | Retorna um resumo de recurso focado sem valores de Secret, dados de ConfigMap ou manifestos brutos. |
get_deployment_diagnostics | Inspeciona a saúde do Deployment, Pods relacionados, ReplicaSets e Eventos. |
get_pod_diagnostics | Inspeciona o status do Pod, condições, estado do contêiner e Eventos. |
get_service_diagnostics | Inspeciona endpoints de Service, Pods de suporte e Eventos. |
✅ Ferramentas de Aprovação do Gateway
| Ferramenta | Propósito |
|---|---|
request_apply_manifest | Dry-run e planejamento de apply do lado do servidor para Deployment, Service ou ConfigMap. |
request_delete_manifest | Dry-run e planejamento de exclusão para tipos de manifesto suportados. |
request_scale_deployment | Dry-run e planejamento de uma alteração na contagem de réplicas de um Deployment. |
request_restart_deployment | Dry-run e planejamento de um restart de rollout de Deployment. |
request_set_deployment_image | Dry-run e planejamento de uma atualização de imagem de contêiner de Deployment. |
propose_plan | Cria um plano Operator Approval Policy pendente de aprovação para o menu de operações do Planejador autônomo. |
execute_approved_plan | Cria o desafio de aprovação no navegador ou executa um plano aprovado e vinculado ao digest após as verificações passarem. |
get_plan_status | Lê o status de aprovação atual de um plano. |
wait_for_plan_approval | Aguarda brevemente uma aprovação de navegador fora do canal e retorna JSON de status sem aplicar o plano. |
Ferramentas diretas de mutação do Kubernetes existem dentro da superfície privada do servidor para o executor do adaptador. O gateway HTTP expõe wrappers request_* mais execute_approved_plan em vez de expor ferramentas destrutivas brutas aos clientes MCP.
⚡ Início Rápido
Pré-requisitos: Docker Compose v2, kubectl, minikube e git.
Revise docs/configuration.md antes de alterar as configurações de tempo de execução.
📦 A partir de Pacotes
O quickstart padrão usa imagens publicadas e padrões locais de demonstração 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 o caminho OAuth local com suporte a Keycloak, o armazenamento de aprovações PostgreSQL e a imagem publicada do gateway com TAG=latest. Fixe uma versão com TAG=v0.1.0 make quickstart. Os padrões confirmados sem SDK vêm do perfil de execução smoke-release: deploy/local-oauth/release.env.example fornece tanto a interpolação do Compose quanto as configurações de runtime do InfraGate__....
🛠️ A partir do código-fonte
Use o modo de código-fonte quando quiser que o gateway, Observer, Planner e Executor sejam compilados a partir do código local. Esse caminho requer o .NET 10 SDK e uma chave de API OpenRouter para os agentes baseados em LLM. O build Docker busca o downstream secundário opcional e somente leitura kubernetes-mcp-server a partir de sua versão oficial, com verificação de checksum contra scripts/kubernetes-mcp-server.manifest.json; execute ./scripts/install-kubernetes-mcp-server.sh (precisa de curl, sha256sum, jq) no host apenas ao executar esse downstream ou seu teste de integração ao vivo diretamente.
export InfraGate__OpenRouter__ApiKey="<openrouter-api-key>"
make quickstart-source
O quickstart a partir do código-fonte gera deploy/generated/local-compose.env (configuração padrão) a partir de deploy/run-profiles.yaml e inicia o gateway, Observer, Planner e Executor a partir de builds locais do código-fonte.
Comandos úteis de acompanhamento:
make quickstart-logs
make quickstart-down
Outros modos de execução e detalhes completos de configuração estão em docs/setup-guide.md.
⌨️ Conectar o Codex CLI
Adicione isto 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"]
Use mcp:tools.write para sessões em que você pretende criar e aplicar planos de mutação. O escopo legado mcp:tools concede acesso total para compatibilidade retroativa.
Em seguida, autentique e inicie o Codex:
codex mcp login infra-gate
codex
💬 Conectar o 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
📦 Imagens de contêiner
As imagens de versão são construídas pelo workflow Docker e publicadas no GHCR e no Docker Hub.
| Registro | Imagem do gateway |
|---|---|
| GitHub Container Registry | ghcr.io/mirusser/kubernetes-mcp-guard-gateway:<tag> |
| Docker Hub | mirusser/kubernetes-mcp-guard-gateway:<tag> |
Use tags de versão específicas para demos estáveis. A tag :dev acompanha o branch de desenvolvimento, e :latest acompanha a versão estável mais recente.
🧩 Compatibilidade
| Área | Suportado / testado |
|---|---|
| .NET | .NET 10 |
| Kubernetes | minikube / cluster local inicialmente |
| Transporte MCP | endpoint MCP HTTP em /mcp |
| OIDC | caminho local/dev com Keycloak; provedores OIDC externos por configuração |
| Registros de contêiner | GHCR, Docker Hub |
| Plataformas | linux/amd64 inicialmente |
🧭 Mapa do projeto
- Runbook do desenvolvedor, execuções locais, contratos de ferramentas MCP e verificação: docs/devs-readme.md.
- Caminhos de configuração, perfis de execução, variáveis de ambiente e orientação de produção: docs/setup-guide.md e docs/configuration.md.
- docs/architecture.md, docs/security-model.md, docs/tool-permissions.md: fluxos de solicitação, limites de segurança e permissões por ferramenta.
- docs/observability-model.md: sinais de telemetria, o caminho de correlação de eventos de auditoria, o Aspire Dashboard somente para desenvolvimento e o navegador Audit Timeline (
/audit/timeline/{planId}). - Serviços de runtime: McpGateway, McpServer, Observer, Planner e Executor.
- Domínio de aprovação e Kubernetes: Approvals, Approvals.Postgres e KubernetesAdapter.
- Validação e demos: tests, exemplo de implantação com falha e SonarQube local.
⚖️ Limites e não objetivos
[!IMPORTANT]
- O projeto é experimental e não certificado para produção.
- O realm local do Keycloak roda em modo de desenvolvimento sobre HTTP e não é um provedor de identidade de produção.
- As proteções contra injeção de prompt são defesa em profundidade, não uma fronteira de segurança rígida garantida.
- A superfície de ferramentas não expõe execução de shell, passagem
kubectl, exec, attach, port-forward, criação de namespace, manipulação de RBAC, leitura de Secrets, leitura bruta de manifests ou gravações no escopo do cluster.- Isto não é um mecanismo completo de políticas Kubernetes e não é um padrão MCP.
Consulte docs/security-model.md para o modelo de ameaças completo.
É uma implementação de referência funcional para um possível perfil de aprovação de mutação MCP, projetada para avaliação técnica inicial em ambientes locais ou estritamente controlados, não infraestrutura certificada para produção.
O código-fonte usa InfraGate como nome interno do projeto.
📜 Governança
- Licença: Apache-2.0
- Política de segurança: SECURITY.md
- Guia de contribuição: CONTRIBUTING.md
- Changelog: CHANGELOG.md
- Processo de versão: docs/releasing.md
Feito com ❤️, ☕ e pequenos guardrails cuidadosos 🛡️✨