Kubernetes-MCP-Guard

AI-safe approval plan gated Kubernetes operations through MCP with OAuth, RBAC, audit, guardrails.

πŸ›‘οΈ Kubernetes MCP Guard

Bridging the gap between AI Agents and Production Infrastructure with a Security-First Gateway.

Unit Tests Integration Tests Docker Quality Gate Status Coverage

.NET 10 Kubernetes Docker AI/LLM

🎯 The Problem

Giving AI agents direct access to Kubernetes is risky. Without a safety layer, an LLM "hallucination" or a prompt injection could accidentally delete a production namespace or leak sensitive secrets.

πŸš€ The Solution

Kubernetes-MCP-Guard is a high-performance gateway built on .NET 10 and the Model Context Protocol (MCP). It provides a secure, audited, and human-gated interface that allows AI agents (like Claude Code or Open WebUI) to interact with your clusters without compromising safety.

πŸ’Ž Key Business Value

  • Human-in-the-Loop Governance: AI can propose changes, but only a human can approve the final execution plan β€” via a separate browser-based approval flow that the MCP client cannot intercept or answer on the human's behalf.
  • Enterprise-Grade Security: Integrated with OAuth-aware authentication and Namespace-scoped RBAC to ensure the AI only sees what it is allowed to see.
  • AI Safety & Auditing: Built-in prompt-injection guardrails and full audit logging for compliance and troubleshooting
  • Cutting-Edge Stack: Architected using the latest .NET 10 features and the industry-standard MCP protocol.

πŸ—ΊοΈ System Architecture

The following diagram illustrates the secure request flow from the AI client through the Guardrails and into the Kubernetes cluster.

---
title: Kubernetes-MCP-Guard Flow
---
flowchart TB
    Client["MCP client<br/>Codex / Open WebUI / LibreChat"]

    subgraph Gateway["HTTP MCP Gateway"]
        Auth["OAuth JWT auth"]
        Guardrails["Prompt-injection guardrails"]
        Audit["Guardrail audit log"]
        Auth --> Guardrails
        Guardrails --> Audit
    end

    subgraph Server["Kubernetes MCP Server"]
        Tools["Typed Kubernetes tools"]
        ReadOnly["Bounded read-only observability"]
        Plans["Approval-gated mutation plans"]
        Tools --> ReadOnly
        Tools --> Plans
    end

    subgraph Kubernetes["Kubernetes boundary"]
        RBAC["Namespace-scoped RBAC"]
        API["Kubernetes API"]
        RBAC --> API
    end

    Client --> Auth
    Guardrails --> Tools
    ReadOnly --> RBAC
    Plans --> RBAC

πŸ” How Approval-Gated Mutations Work

The diagram below shows what happens when an AI agent tries to make a change to your cluster. The key point: the AI cannot approve its own requests. Approval happens in your browser, on a completely separate channel with its own login.

---
title: Out-of-Band Approval Flow
---
flowchart TB
    classDef ai      fill:#e8f0fe,stroke:#4285f4,color:#1a1a2e,font-size:13px
    classDef browser fill:#e6f4ea,stroke:#34a853,color:#1a1a2e,font-size:13px
    classDef gate    fill:#fff3e0,stroke:#fb8c00,color:#1a1a2e,font-size:13px
    classDef k8s     fill:#fce4ec,stroke:#e53935,color:#1a1a2e,font-size:13px

    subgraph AI["β‘  AI / MCP Channel"]
        direction TB
        A1["πŸ€– AI agent requests a change e.g. scale deployment to 3 replicas"]
        A2["Gateway validates identity; server dry-runs and creates a pending plan locked with a SHA-256 hash"]
        A3["β›” AI receives an approval URL only.
         It cannot approve on your behalf"]
        A4["AI calls apply again once human has approved"]
    end

    subgraph OOB["β‘‘ Your Browser  β€”  separate login, separate session"]
        direction TB
        B1["πŸ”— You open the approval URL in your browser"]
        B2["You log in with OAuth independent of the AI session"]
        B3["Browser shows the real plan rendered by the Gateway from disk not by the AI"]
        B4["You review: operation, namespace, affected objects, expiry time"]
        B5["βœ… You click Approve  or  ❌ Deny"]
    end

    K8s["☸️ Kubernetes Change is applied only after both channels agree"]

    A1 --> A2 --> A3
    A3 -.->|"URL shown to AI, opened by you"| B1
    B1 --> B2 --> B3 --> B4 --> B5
    B5 -->|"Approval recorded with identity binding"| A4
    A4 --> K8s

    class A1,A2,A3,A4 ai
    class B1,B2,B3,B4,B5 browser
    class K8s k8s

Even if the AI agent is compromised, it cannot self-approve. The approval must come from your browser session a channel the AI has no control over. Simplified architectural graph. Full version here

πŸ› οΈ Technical & Architectural Highlights

  • AI Integration & Safety: Deep implementation of Model Context Protocol (MCP), handling tool contracts, out-of-band approval workflows, and mitigating prompt-injection risks within model-visible data.

  • Security & Identity: Implemented OAuth 2.0 resource-server patterns, including scope enforcement, identity-based audit logging, and strict Least-Privilege RBAC for Kubernetes interactions.

  • Cloud-Native Engineering: Advanced usage of the Official Kubernetes .NET Client, utilizing Server-Side Apply (SSA) for dry-run planning, real-time Pod log streaming, and namespace isolation.

  • Modern .NET 10 Stack: Built with a focus on Clean Architecture, leveraging Dependency Injection, high-performance Async/Await patterns, and a modular project structure that separates Auth, Gateway, and Core logic.

  • Product Mindset: Prioritized a "small operational surface" and human-readable audit logs, ensuring the tool is as safe for a human SRE as it is powerful for an AI agent.

πŸ—οΈ Implementation Details:
  • Exposes Kubernetes operations through the Model Context Protocol (MCP), with a stdio Kubernetes server behind a local HTTP gateway.
  • Uses the Kubernetes API via KubernetesClient; it does not shell out to kubectl for runtime operations.
  • Adds OAuth authentication at the gateway, including MCP protected-resource metadata, insufficient-scope challenges, and browser approval sessions.
  • Applies prompt-injection guardrails around model-visible tool input/output, with warn, redact, and audit behavior.
  • Keeps mutation paths approval-gated: create a plan first, approve it in the Gateway browser UI, then apply the exact approved plan.
  • Limits Kubernetes blast radius with namespace-scoped RBAC and typed, bounded tool surfaces.

πŸ“¦ Container Images

Images are automatically built, scanned, and published to multiple registries for every release.

RegistryGateway (Core)Dev Issuer (Auth)
GitHub (GHCR)ghcr.io/mirusser/kubernetes-mcp-guard-gateway:<tag>ghcr.io/mirusser/kubernetes-mcp-guard-devissuer:<tag>
Docker Hubmirusser/kubernetes-mcp-guard-gateway:<tag>mirusser/kubernetes-mcp-guard-devissuer:<tag>

Versioning: Use specific tags (e.g., :v0.1.0) for production stability. The :latest tag tracks the most recent stable release.

Example pull:

docker pull ghcr.io/mirusser/kubernetes-mcp-guard-gateway:latest

⚑ Quick Start

Option 1 β€” Run from published images (no build required)

Prerequisites: Docker Compose v2, minikube, git.

git clone https://github.com/mirusser/Kubernetes-MCP-Guard.git

cd Kubernetes-MCP-Guard

./scripts/create-demo-kubeconfig.sh --compose
TAG=latest docker compose -f deploy/mode-c/compose.release.yaml up

Replace latest with a specific release tag (e.g. v0.1.0) for a stable run. Available tags are listed on the Releases page.

Connect Codex CLI:

  1. Add this block to ~/.codex/config.toml (create the file if it does not exist):
[mcp_servers.infra-gate]
url = "http://127.0.0.1:3001/mcp"
oauth_resource = "http://127.0.0.1:3001/mcp"
scopes = ["mcp:tools"]
  1. Then log in:
codex mcp login infra-gate # authenticate 
codex # run codex

Connect Claude Code:

# 1. Add/register the MCP server
claude mcp add-json --scope user infra-gate \
  '{"type":"http","url":"http://127.0.0.1:3001/mcp","oauth":{"scopes":"mcp:tools"}}'

# 2. Start Claude Code
claude

# 3. Inside Claude Code, open MCP manager/auth flow
/mcp

After successful log in you may start with:

Explain briefly what are the capabilities of MCP server: infra-gate

Option 2 β€” Build and run from source

Prerequisites: .NET 10 SDK, Docker Compose v2, minikube, git.

./scripts/create-demo-kubeconfig.sh --compose
docker compose -f deploy/mode-c/compose.yaml up --build

Connect Codex the same way as Option 1.

Other run modes and full setup details are in the Setup Guide.

🧰 Current Capabilities

πŸ›‘οΈ Gateway Protections

LayerBehavior
AuthenticationOAuth 2.1 JWT for MCP plus browser OAuth cookie for approvals
Prompt-injection guardrailsWarn and redact suspicious model-visible input/output
Audit loggingJSONL guardrail audit with identity resolution
MCP complianceStreamable HTTP transport, protected-resource metadata, step-up authorization

πŸ”Ž Read-Only Observability

ToolPurpose
get_allowed_namespacesNamespace allow-list the server is configured to access
get_k8s_statusDeployments, Services, ConfigMaps, Pods, and ReplicaSets in a namespace
get_k8s_eventsBounded events.k8s.io/v1 cluster diagnostics
get_pod_logsBounded Pod log reads (tail lines + byte cap)
get_k8s_resourceFocused resource summary β€” no Secret values, ConfigMap data, or raw manifests
get_deployment_diagnosticsDeployment health, related Pods, ReplicaSets, and Events
get_pod_diagnosticsPod status, conditions, container state, and Events
get_service_diagnosticsService endpoints, backing Pods, and Events

βœ… Approval-Gated Mutations

ToolPurpose
request_apply_manifestDry-run and plan a server-side apply for Deployment, Service, or ConfigMap
request_delete_manifestDry-run and plan a resource deletion
request_scale_deploymentDry-run and plan a replica count change
request_restart_deploymentDry-run and plan a rollout restart
request_set_deployment_imageDry-run and plan a container image update
apply_approved_planRepeat dry-run, then apply an exact-hash-verified, user-approved plan

🎬 See It In Action

End-to-end walkthrough of the approval-gated workflow against a deliberately broken Deployment: docs/demo-failing-deployment.md. Uses the demo manifests under examples/failing-deployment/.

Compatibility

AreaSupported / tested
.NET.NET 10
Kubernetesminikube / local cluster initially
MCP transportHTTP MCP endpoint at /mcp
OIDCDevIssuer (dev), Keycloak documented; Entra ID later
Container registriesGHCR, Docker Hub
Platformslinux/amd64 initially

🧭 Explore The Project

Naming note: The public name is Kubernetes MCP Guard. The internal codename InfraGate appears in .slnx, project folders, env-var prefixes (INFRA_GATE_*), and Docker labels. They refer to the same project; the rename is gradual and does not change runtime behavior.

βš–οΈ Governance & Policies


Related Servers

NotebookLM Web Importer

Import web pages and YouTube videos to NotebookLM with one click. Trusted by 200,000+ users.

Install Chrome Extension