Join our Newsletter — 33% off our NHI Course
Home› Guides› Running MCP Servers on Kubernetes: Isolation, Identity and…
Guide MCP, Protocols & Agent Platforms

Running MCP Servers on Kubernetes: Isolation, Identity and Network Policy

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 14 November 2026 17 min read
On this page

An MCP server on Kubernetes is a pod that turns model output into authenticated calls against your systems, so a weak namespace, a broad service account or an open egress path decides how far one bad tool call or one compromised server can reach. Platform teams are moving remote MCP servers from developer machines and ad hoc virtual machines onto shared clusters, often dozens of servers for different teams or customers. The protocol-level controls (OAuth, Origin checks, tool design) are covered in the Remote MCP Server Hardening Guide, and the NetworkPolicy mechanics are in the Kubernetes Network Policy Guide. This guide is the deployment pattern that sits between them: how to lay out namespaces, identities, network paths and authentication sidecars for MCP servers on a cluster. It is written for platform engineers, Kubernetes administrators and security architects. Managed platforms are listed alphabetically (AKS, EKS, GKE); order is not a ranking.

Key takeaways

  • One namespace per server and tenant. The namespace is where Kubernetes attaches quotas, Pod Security admission, NetworkPolicy and service accounts, so it is the natural blast-radius unit for an MCP server.
  • The pod gets a workload identity, never a key. Use projected, audience-bound service account tokens federated to the cloud provider, and keep the default API token out of the pod unless the server genuinely calls the Kubernetes API.
  • Egress is the real tool boundary. A tool that can reach the internet, the cloud metadata endpoint or another tenant's server is a tool an attacker can steer there. Default-deny egress and allow only each server's named upstreams.
  • Authenticate at the pod, not only at the edge. An ingress or gateway that validates OAuth tokens is not enough if other pods can call the server directly; validate in the server or a sidecar in the same pod.
  • Know which protocol revision you run. Revision 2026-07-28 removed protocol-level sessions, which makes horizontal scaling simple; older revisions with session IDs need session-aware routing and per-session state that must not leak between users.

What changes when MCP servers move onto a cluster

A remote MCP server is an OAuth 2.1 resource server under the MCP authorisation specification: it must validate that each access token was issued for it, and it must not accept or pass on any other token. On Kubernetes that server also becomes a workload with its own identity, network position and neighbours. Four properties make MCP servers riskier than an average microservice on the same cluster:

  • Model-directed actions: tool arguments come from a model that may be acting on injected content, so the server will try to reach whatever a crafted argument points at.
  • Upstream credentials: most servers hold tokens for SaaS, databases or cloud APIs. A pod compromise exposes those credentials and anything else the pod can reach, including the cloud instance metadata API (MITRE ATT&CK T1552.005) and application tokens (T1528).
  • Third-party code: many servers are community packages or vendor images that run unreviewed dependencies, and some run code supplied at runtime.
  • Multi-tenancy pressure: it is tempting to run one server per tool for every team or customer on one shared node pool, which concentrates very different trust levels.

The Smithery.ai MCP hosting breach shows the hosting-layer version of this risk: one deployment token reachable from a build machine gave researchers access to an organisation holding 3,243 apps, mostly hosted MCP servers, and to a client API key in one server's traffic. The controls below are about stopping that kind of single credential or single pod from reaching everything.

Namespace and tenancy layout

The Kubernetes multi-tenancy documentation describes a namespace per tenant as the usual pattern and is clear that containers are a weaker boundary than virtual machines because they share the host kernel. Choose the layout by trust level, not by convenience.

LayoutWhen to useIsolation you getCost and limits
Namespace per MCP server, shared nodesInternal servers built or reviewed by your own teams, one trust levelSeparate service accounts, RBAC, quotas, NetworkPolicy and Pod Security level per serverKernel, kubelet and API server shared; a container escape (T1611) reaches neighbours
Namespace per tenant and server, dedicated node pool per tenantCustomer-facing servers, or servers holding regulated dataTaints and tolerations keep each tenant's pods on its own nodes, so an escape reaches only that tenant's podsMore nodes; Kubernetes notes that the kubelet and API server are still shared
Sandboxed runtime through RuntimeClassThird-party servers, servers that execute code or run unreviewed packagesEach pod in a VM-based or userspace-kernel sandbox, which Kubernetes recommends for untrusted codeRuntime overhead and compatibility testing; needs nodes configured with the handler
Cluster per tenantHard isolation requirements or tenants with different compliance regimesSeparate control planes, identities and networksHighest operational cost

Name namespaces consistently, for example mcp-<server>-<tenant>, and label them with owner, data classification and tenant. Those labels are what NetworkPolicy namespace selectors, admission policies and cost reports use, so they must be set by the platform pipeline and protected from change by the server team. For each namespace apply:

  • Pod Security admission at Restricted: label the namespace pod-security.kubernetes.io/enforce: restricted. The Restricted profile requires runAsNonRoot: true, allowPrivilegeEscalation: false, dropping ALL capabilities (only NET_BIND_SERVICE may be added back), a RuntimeDefault or Localhost seccomp profile and an allowlist of volume types. Most MCP servers need none of the exceptions.
  • ResourceQuota and LimitRange: cap CPU, memory and pod count per namespace so a looping agent or a costly tool cannot starve other tenants. Rate limits per user still belong in the server or gateway.
  • Admission rules: allow images only from your registry and signed by your pipeline, block hostNetwork, hostPath and privileged pods, and require a runtimeClassName for namespaces labelled as third-party. See the Kubernetes Admission Control Guide.
  • Read-only root filesystem with an emptyDir scratch volume: so per-request temporary files disappear with the pod.

Workload identity for upstream calls

Each MCP server needs its own identity for the systems its tools call, separate from the user tokens it receives. On Kubernetes that identity is the pod's service account, exchanged for short-lived cloud credentials through the provider's workload identity feature. One service account per server per tenant keeps permissions narrow and audit trails attributable.

Kubernetes service account tokens

  • Turn off the default API token: set automountServiceAccountToken: false on the service account or pod (the pod setting wins). Most MCP servers never call the Kubernetes API, and a mounted token is the first thing an attacker looks for.
  • Project only the tokens you need: a projected serviceAccountToken volume with a specific audience and expirationSeconds. The kubelet refreshes the token when it is older than 80 percent of its lifetime or 24 hours, and the application must reload the file.
  • Validate with TokenReview when your own services accept these tokens: Kubernetes recommends TokenReview over offline OIDC validation because tokens bound to a deleted pod are invalidated immediately, and it says applications should always check that the audience matches.
  • Bind RBAC to nothing by default: if a server must read ConfigMaps or Secrets, grant a namespaced Role on named resources only. See the Kubernetes Workload Identity Checklist for the full policy set.

Cloud workload identity by platform

PlatformMechanismHow the pod is boundSetting to watch for MCP tenants
Azure Kubernetes Service (AKS)Microsoft Entra Workload ID: the cluster's OIDC issuer signs a projected token that Entra ID exchanges through a federated identity credentialService account annotation azure.workload.identity/client-id and pod label azure.workload.identity/use: "true"; the webhook sets AZURE_FEDERATED_TOKEN_FILE; direct federation uses audience api://AzureADTokenExchangeToken expiry is configurable from 3600 to 86400 seconds; keep it at the low end and use one managed identity per server and tenant
Amazon Elastic Kubernetes Service (EKS)EKS Pod Identity: an association maps an IAM role to a service account in a namespace in a cluster; the agent DaemonSet serves credentials on 169.254.170.23Role trust policy for the pods.eks.amazonaws.com service principal plus the associationAWS notes that if IMDS is not restricted, containers may reach the node role or other pods' roles, and hostNetwork pods always have IMDS access; restrict IMDS and block hostNetwork
Google Kubernetes Engine (GKE)Workload Identity Federation for GKE: IAM principals identify a namespace and service account; the GKE metadata server DaemonSet answers token requestsIAM bindings on the principal .../subject/ns/NAMESPACE/sa/SERVICEACCOUNTGoogle notes IAM does not distinguish clusters that share a workload identity pool and principal; put isolated tenants in separate projects or keep namespace names distinct, and use IAM conditions

Platform-specific hardening is covered in the AKS Identity Hardening Guide, the EKS Identity Hardening Guide and the GKE Identity Hardening Guide. Whatever the platform, the workload identity reaches cloud APIs only; tokens for SaaS and third-party APIs still need a secrets manager or token exchange, as the Remote MCP Server Hardening Guide describes. Never mount one tenant's upstream secret into a pod that serves another tenant.

Egress and ingress with NetworkPolicy

Inbound MCP traffic should arrive from one place, the ingress controller or MCP gateway, and outbound traffic should go only to the upstreams that server's tools need. Build this as a policy set per MCP namespace on top of the cluster's default deny.

PolicyDirectionAllowWhy it matters for MCP
Default denyIngress and egressNothingEvery later rule is an explicit decision you can review
DNSEgressUDP and TCP 53 to the cluster DNS pods onlyWithout it nothing resolves; restricting it to cluster DNS stops direct lookups to attacker resolvers
From gatewayIngressThe MCP port from pods labelled as the gateway or ingress controller, in their namespaceOther tenants' pods cannot call the server directly and bypass edge authentication
Named upstreamsEgressSpecific CIDRs or, with a CNI that supports it, fully qualified domain names on 443A prompt-injected tool call cannot reach arbitrary hosts; NetworkPolicy itself has no domain names, so FQDN rules depend on the CNI
Identity endpointEgressThe workload identity agent or metadata server address your platform uses, where the pod needs itNeeded for token exchange; block the general instance metadata endpoint (169.254.169.254) for everything else
Kubernetes APIEgressDenied unless the server needs itLimits discovery and abuse of any token the pod holds
  • Egress proxy for internet tools: for servers whose tools fetch arbitrary URLs (search, browsing, web fetch), send egress through a filtering proxy that logs every destination, rather than opening 0.0.0.0/0. See the Agent Egress Control and Network Isolation Guide.
  • Prove enforcement: the API server accepts NetworkPolicy objects even when the CNI ignores them. Test each policy from a debug pod in the namespace before trusting it.
  • Cluster-wide guardrails: a platform-owned baseline (cluster network policy or CNI global policy) should deny metadata access and cross-tenant traffic even if a namespace owner deletes their own policies.

Authentication at the pod: sidecars and gateways

The MCP server must validate tokens for itself, but many teams deploy community servers that implement no authentication, or want one consistent implementation across languages. Kubernetes native sidecars (init containers with restartPolicy: Always, enabled by default from 1.29 and stable in 1.33) run for the life of the pod and start before the main container, which makes an authentication proxy in the same pod practical.

PatternWhat validates the tokenStrengthWeakness
Edge only (ingress or MCP gateway)The gatewayOne place to manage OAuth, rate limits and loggingAnything that reaches the pod directly bypasses it, unless NetworkPolicy restricts ingress to the gateway
Auth sidecar in the podA proxy container listening on the pod port; the server binds to localhostWorks for servers with no auth; uniform audience and issuer checks; the server port is not reachable from the networkThe sidecar must pass verified identity to the server (for example a signed header) and the server must trust only that
In-server validationThe MCP server's own middlewarePer-tool authorisation decisions use the verified user and scopes directlyQuality varies between servers and languages
Service mesh mutual TLS plus one of the aboveMesh identity for the caller workload, OAuth for the userProves which gateway or agent runtime is calling, independent of network positionMesh identity says nothing about the end user; it complements OAuth, never replaces it

A sound default is gateway plus in-pod validation: the gateway handles discovery, rate limits and logging, and the sidecar or server repeats audience, issuer, expiry and scope checks. Under the MCP specification the server must validate that each token was issued for it and must not pass the client's token to upstream APIs; a sidecar that forwards the original bearer token to the server for upstream use breaks that rule. Bind the MCP container to 127.0.0.1 when a sidecar fronts it, so the only path in is through the proxy. See the Service Mesh Security Guide for mesh identity.

Scaling, routing and the protocol revision

Revision 2026-07-28 of the MCP specification changed Streamable HTTP: protocol-level sessions and the standalone GET stream were removed, servers ignore any Mcp-Session-Id header, and SSE streams are scoped to a single request and cannot be resumed. Every request also carries MCP-Protocol-Version, Mcp-Method and, for tool calls and reads, Mcp-Name headers so that load balancers and gateways can route and inspect without parsing the body.

  • Stateless revision: any replica can serve any request, so a normal Deployment with a HorizontalPodAutoscaler works. Keep per-user state in a store keyed by verified user and tenant, never in process memory shared between requests.
  • Older revisions (2025-03-26 to 2025-11-25): a session ID minted at initialisation must reach the same replica or a shared session store. Sticky routing on the session header ties a user to a pod; design so a session cannot be resumed by a different user presenting the same ID.
  • Header routing needs body validation: the specification requires servers to reject header and body mismatches with HTTP 400 and error -32020, and says intermediaries that route or rate-limit by tenant on mirrored headers should reject requests whose protocol version predates that validation. A gateway that routes by Mcp-Name on a server that does not validate is a bypass.
  • Streaming through proxies: the specification advises sending X-Accel-Buffering: no on SSE responses and periodic keep-alive comments on long-lived subscriptions/listen streams; set ingress idle timeouts to match, or long tool calls will fail mid-stream.
  • Graceful shutdown: set a termination grace period longer than your longest tool call so rolling updates do not cut off in-flight actions half-applied.

Rolling out the pattern

  1. Inventory: list every MCP server on the cluster with owner, image source, tenants served, upstreams called and protocol revision. The MCP Server Inventory Template gives the fields.
  2. Namespaces and Pod Security: move each server into its own namespace. Apply Restricted in warn and audit modes first, fix violations, then switch to enforce.
  3. Identity: create one service account per server and tenant, disable automount, set up workload identity and remove static cloud keys. Remove old keys only after the new path has served traffic for a full release cycle.
  4. Network: apply default deny with DNS and gateway rules, observe flows in the CNI's audit or staged mode, then add upstream egress rules and enforce. Keep the previous policy set in version control for rollback.
  5. Authentication: add the sidecar or in-server validation, then restrict ingress to the gateway only.
  6. Third-party servers: move them to a sandboxed RuntimeClass or a dedicated node pool and pin image digests.
  7. Test: from a pod in another tenant namespace, confirm you cannot reach the server; from the server pod, confirm the metadata endpoint, the API server and an unlisted host are unreachable; replay a token issued for another server and confirm it is rejected.

Detection and measurement

Collect Kubernetes audit logs for changes to MCP namespaces, policies, service accounts and RoleBindings, CNI flow logs for denied egress, and the server or gateway's tool call logs. Alert on denied egress to the metadata endpoint or unknown hosts, new RoleBindings in MCP namespaces, pods created with hostNetwork or privileged settings, exec into MCP pods, and tokens rejected for wrong audience. The Kubernetes Audit Log Detection Guide covers the audit queries.

  • Namespace isolation coverage: percentage of MCP servers in their own namespace with Restricted enforced.
  • Egress allowlisting: percentage of MCP namespaces with default-deny egress and named upstreams only.
  • Static credentials remaining: count of MCP pods using mounted cloud keys instead of workload identity.
  • Direct-path exposure: MCP services reachable from outside the gateway namespace (target zero).
  • Sandboxed third-party servers: percentage of third-party or code-executing servers on a sandboxed runtime or dedicated nodes.

Framework mapping

ControlNIST SP 800-53 Rev. 5NIST CSF 2.0MITRE ATT&CK technique addressed
Namespace, node and runtime isolationSC-39 Process Isolation, SC-7 Boundary ProtectionPR.IR-01T1611 Escape to Host
Default-deny egress and named upstreamsAC-4 Information Flow Enforcement, SC-7PR.IR-01T1552.005 Cloud Instance Metadata API
Per-server workload identity, no static keysIA-9 Service Identification and Authentication, AC-6 Least PrivilegePR.AA-01, PR.AA-05T1528 Steal Application Access Token
Pod Security Restricted and admission rulesCM-7 Least FunctionalityPR.PS-01T1610 Deploy Container
Audit and flow monitoringAU-6 Audit Record Review, Analysis, and ReportingDE.CM-09All of the above

Common failure patterns

  • All MCP servers in one namespace: one service account, one Secret set and one policy for every server, so any compromise reaches every upstream.
  • Gateway-only authentication: the gateway validates tokens but the server's Service is reachable from every pod in the cluster.
  • Open egress for convenience: 0.0.0.0/0 allowed because one tool fetches web pages, which also opens the metadata endpoint and every internal service.
  • Shared identity across tenants: one cloud role or one workload identity principal serving several tenants, or, on shared projects, identical namespace names in clusters with different trust.
  • Hosting credentials within reach of untrusted code: deployment and registry tokens on build or runtime nodes that also run server code, as in the Smithery case.
  • Session IDs treated as authentication: on older protocol revisions, routing or resuming by session ID without re-checking the bearer token on every request.

Practitioner checklist

  • Give every MCP server and tenant its own namespace with owner, tenant and data labels set by the pipeline.
  • Enforce Pod Security Restricted on MCP namespaces after a warn and audit period.
  • Disable service account token automount and use audience-bound projected tokens only where needed.
  • Use the platform's workload identity with one identity per server and tenant; remove static cloud keys.
  • Apply default-deny ingress and egress, allow DNS, gateway ingress and named upstreams, and block the metadata endpoint.
  • Validate OAuth tokens in the pod (server or sidecar) as well as at the gateway, and bind the server to localhost behind a sidecar.
  • Run third-party and code-executing servers on a sandboxed RuntimeClass or dedicated nodes.
  • Record the protocol revision per server and configure routing, timeouts and state handling to match it.
  • Test isolation from another tenant's namespace and from the server pod itself after every policy change.

Standards and references

Related NHI Mgmt Group resources: Remote MCP Server Hardening Guide · Kubernetes Network Policy Guide · Multi-Tenant Remote MCP Server Design · MCP Gateway and MCP Server Governance Guide · Kubernetes Security Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 14 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org