BoundBench

Amazon EKS MCP Server

MCP server for EKS cluster management and Kubernetes resources

github.com/awslabs/mcp › src/eks-mcp-server · 2026-10-03 · 93991b8

Defense-in-depth score

4.7 / 10

Minimal

With no flags this server is read-only: every tool that could change a cluster, deploy a CloudFormation stack, or edit IAM refuses in code, and logs, events and Secret reads are withheld. But it runs on the operator's full ambient AWS identity, its tools carry no risk annotations, and the README's own install buttons switch on both --allow-write and --allow-sensitive-data-access. Once they're on, the model can delete Kubernetes objects, deploy any CloudFormation template with IAM capability, and attach any IAM policy to any role, with no confirmation. Even in the default, the sensitive-data gate does not cover every path.

Key gaps (1)

  1. Every AWS and Kubernetes call uses the operator's full ambient identity (README recommends IAMFullAccess for writes), so once the read-only check is off or bypassed nothing confines what the server can do, including adding arbitrary IAM policies to any role. C1 · Identity & least privilege

Criteria

C1 Identity & least privilege

Minimal 0.40 / 1.00

The server signs every AWS and Kubernetes call with the operator's own ambient credentials: the boto3 default chain or AWS_PROFILE, and for Kubernetes a token minted from that same identity for whatever cluster name the model supplies. Nothing narrows the credential itself. What the server does have is a deterministic read-only switch, on by default, that every mutating tool checks before touching a client, so the default server can only describe and list. Pass --allow-write, as every README install example does, and the model can create or delete any Kubernetes object, deploy CloudFormation stacks with IAM capability, and attach arbitrary inline policies to any IAM role, including the server's own.

C2 Approval gates

Minimal 0.33 / 1.00

The server owns no approval loop, so it is rated on what it gives the host. No tool carries read-only or destructive annotations, and two tools (manage_k8s_resource and manage_eks_stacks) mix read and write operations behind one name, so a host cannot tell a describe from a delete. There is no dry-run or preview. What protects the default install is the server-enforced read-only mode: with no flags, no tool can change anything. With --allow-write, deletes, stack deploys and IAM policy changes run immediately with no server-side confirmation.

C3 Tool & action scoping

Minimal 0.38 / 1.00

The tools are broad. manage_k8s_resource performs any CRUD operation on any kind in any namespace of any cluster the model names; apply_yaml applies any manifest file; manage_eks_stacks deploys any CloudFormation template file with IAM capability; and add_inline_policy accepts arbitrary policy statements for any role. File paths are resolved and checked only against a short denylist of sensitive directories, and the app-manifest generator pastes unvalidated values (image, namespace, CPU, memory) into YAML by string replacement. The default read-only mode keeps the write tools inert, but the read tools still reach every resource kind across every reachable cluster.

C4 Code-execution isolation

Minimal 0.15 / 1.00

The server never runs a shell, eval, or subprocess locally. It can, however, have model-chosen code run elsewhere: apply_yaml and manage_k8s_resource can create pods with any image and any security context, and manage_eks_stacks deploys any CloudFormation template with IAM capability in the operator's account. There is no isolation around any of these. The only thing standing in the way is the read-only default: without --allow-write none of these paths runs.

C5 Untrusted input blast radius

Moderate 0.55 / 1.00

Tool results come back as a short status line plus a JSON document carrying the cluster, namespace, kind, and name each result came from, kept separate from instructions; the troubleshooting search returns the remote service's text verbatim. Nothing marks content as untrusted, and resource annotations, ConfigMaps and pod specs, which anyone who can edit cluster objects controls, reach the model as plain data. The defaults drop two risky legs: logs and events are withheld, and nothing can be changed. A hijacked host agent can still read sensitive cluster data through this server, but cannot use it to act or send data out.

C6 Memory, context & configuration integrity

N/A · full credit 1.00 / 1.00

The server keeps no memory, conversation store, or retrieval index and reads no instruction or configuration files from the working directory. Its configuration comes only from command-line flags and environment variables (auth mode, AWS profile, region, KUBECONFIG path), all set by the operator. Cluster objects the model writes and later reads back are untrusted input, covered in C5.

C7 Third-party extensions

N/A · full credit 1.00 / 1.00

The server loads no plugins, launches no MCP servers or subprocesses, installs no packages, and deserializes no model files. Container images and CloudFormation templates the model asks it to deploy run in the cluster or AWS account and are scored under C4 and C3.

C8 Secrets & sensitive-data protection

Minimal 0.30 / 1.00

The server never puts its own AWS credentials or Kubernetes token into tool output; the Kubernetes token is minted from the ambient identity and cached for 14 minutes. A sensitive-data flag, off by default, withholds pod logs, events, CloudWatch logs and Secret reads. But it is only a gate on a few tool paths: its enforcement is not complete, pod and deployment specs with plaintext environment values are readable, and nothing is redacted anywhere. Logging goes through an unconfigured loguru logger, which emits debug lines (including any proxy URL) to stderr.

C9 Audit & traceability

Minimal 0.33 / 1.00

Each tool writes free-text log lines prefixed with the MCP request ID, naming the operation and target (for example 'Deleted Pod ns/name') and recording write-mode and sensitive-data refusals as errors. The logger is never configured, so lines go to stderr at the library's default level, and FASTMCP_LOG_LEVEL, which the README sets, is not read. Nothing is written to a file, arguments such as patch bodies or policy statements are not recorded, nothing identifies the requesting user, and nothing protects the record from tampering.

C10 Limits & kill switch

Minimal 0.25 / 1.00

The server bounds little of its own work. Pod logs default to the last 100 lines and 10 KB, CloudWatch queries to 50 entries, but the caller can raise each. Resource listing has no limit, Kubernetes and knowledge-base HTTP calls have no timeout, and the CloudWatch poll loop calls a blocking sleep inside an async handler for up to 60 attempts, leaving the query running when it gives up. There is no rate limit or cancellation.