SafetyCard Request a review

K8sGPT

CNCF Kubernetes diagnostics CLI/operator that scans clusters and explains issues with LLMs; ships MCP server

github.com/k8sgpt-ai/k8sgpt · 2026-10-03 · 635d9b1

Defense-in-depth score

5.8 / 10

As a CLI, k8sgpt is a fixed pipeline, not a tool-using agent: hard-coded read-only analyzers collect cluster problems, the model explains each one in text, and nothing the model says is executed. A hijacked model can only mislead the operator. The main posture gaps are elsewhere: the CLI uses the operator's full kubeconfig with no narrowing, keeps no record of what it sent to the AI provider, and stores the provider key in plaintext. The score does not cover `k8sgpt serve --mcp`, which hands an MCP host tools that read any Secret and rewrite cache and analyzer endpoints. Assess that mode separately before using it.

Safest setup

In the CLI analyze flow the model only writes explanations: the analyzers are fixed read-only code and nothing the model says is run. The weak spots are around it, with the full kubeconfig identity, a plaintext provider key and no record of what was sent, so the safest setup narrows the identity and the data and adds containment outside the tool. The serve and MCP modes were not scored and need their own assessment.

SetupHowWhat it gives you
A read-only identityPass --kubeconfig and --kubecontext for a context bound to a view-only ServiceAccountThe cluster itself refuses writes and reads outside that role, whatever the tool does C1
A scoped provider keyUse an AI provider key made for k8sgpt alone, with a spending limit set at the providerA leaked key reaches only this use and a bounded spend C8
Only the namespaces needed--namespace <ns> and --filter <analyzers> on each analyze runEach run reads and sends to the provider only the resources you chose C1
Anonymized prompts--anonymize on each explain runObject names and labels are masked before they reach the provider C8
Built-in analyzers onlyKeep the default custom-analysis off by leaving out -zEvery analyzer result comes from code shipped in k8sgpt C7
Fresh answers per cluster--no-cache when switching clusters, and k8sgpt cache purge --all to clear stored answersExplanations come from the current cluster's problems, not an earlier stored answer C6
Cluster-side audit loggingTurn on Kubernetes API audit logging for the identity k8sgpt usesA record of what each run read, which the CLI does not keep itself C9

Approving with confidence

  • There are no approval prompts; read each suggested fix and check it against the cluster before running it, since workload messages can shape the advice.

Handling data

  • k8sgpt.yaml in the user config directory holds the provider key in plaintext; keep it readable only by your user.
  • Cached answers stay in the user cache directory with no expiry; clear them with the purge command when they are no longer needed.

Criteria

C1 Identity & least privilege

0.30 / 1.00

The CLI uses whatever Kubernetes credentials are in the operator's kubeconfig (in-cluster service account first, otherwise the current context), so it typically runs with cluster-admin-level authority and never narrows it. What limits the damage is the design: every Kubernetes request is a hard-coded list or get call in the analyzers, the model never sees or uses the credentials, and nothing on the analyze path writes to the cluster. A hijacked model therefore cannot use the identity at all, but k8sgpt itself still reads cluster-wide with the full credential, including Secret objects it fetches to check that they exist.

C2 Approval gates

N/A · full credit 1.00 / 1.00

In the scored CLI flow the model only returns text. It has no tools, and k8sgpt never acts on what the model says: the answer is stored in a local cache and printed. All Kubernetes calls on this path are read-only, so no consequential action exists that would need approval. The MCP server mode (not scored) is different: an MCP host can call a config tool that persists new custom-analyzer endpoints and remote cache buckets with no confirmation step.

C3 Tool & action scoping

N/A · full credit 1.00 / 1.00

The model is given no tools, so it never chooses arguments, paths, URLs or queries. Which analyzers run, the namespace and the label selector come from the operator's command-line flags, and the Kubernetes calls are fixed in code. Tool-argument scoping has no surface in the scored mode. The MCP server (not scored) does expose model-callable tools, and those include reading any Secret by name.

C4 Code-execution isolation

N/A · full credit 1.00 / 1.00

Nothing interprets model output or cluster content as code. The only process launch in the codebase opens a fixed OpenAI key-generation URL in the user's browser for `k8sgpt generate`. There is no shell tool, no eval, no template rendering of model text, and no plugin loading.

C5 Untrusted input blast radius

Hardened 0.88 / 1.00

k8sgpt sends attacker-influenced cluster text to the model: event messages, container status messages and probe output that any workload owner can shape. The only in-prompt defence is a set of triple-dash delimiters. The pipeline is fixed in code before any of that text is read, and the model has no tools, so a hijacked model can only change the explanation the operator reads. The residual risk is the human: injected text can produce convincing but harmful remediation advice for an operator who usually holds cluster-admin, and model output is printed to the terminal without stripping control characters.

C6 Memory, context & configuration integrity

0.35 / 1.00

Configuration is read only from user scope: the XDG config directory, an explicit --config flag, or K8SGPT_* environment variables. Nothing is loaded from the working directory. The one persistent store the model influences is the response cache: each AI answer is written verbatim and served again, without calling the model, whenever the same failure text recurs. Entries carry no provenance and never expire. The default file cache is private to the OS user (mode 0600), but the cache key ignores which cluster or context produced it. A poisoned explanation can persist across sessions, though it only affects text shown to the operator. `k8sgpt cache purge` clears it.

C7 Third-party extensions

0.38 / 1.00

Nothing third-party is enabled by default. There are two opt-in extension paths. The first is custom analyzers: remote gRPC services the operator registers and enables with the -z flag. They receive an empty request and no credentials, but the connection is unauthenticated plaintext and nothing pins or verifies the endpoint. The second is `integration activate keda`, which installs a version-pinned KEDA Helm chart from the official repository using the operator's kubeconfig, with no digest or signature check. The repository and version can be overridden through environment variables. A malicious chart would run in the cluster with whatever RBAC it declares.

C8 Secrets & sensitive-data protection

0.38 / 1.00

The AI provider key is written in plaintext to the user's k8sgpt.yaml through viper. No file mode is set, so viper's default world-readable 0644 likely applies (inferred from the library default, not verified). `k8sgpt dump` masks the key and `auth list` never prints it. There is no telemetry or crash reporting, verbose output prints only the base URL and model, and cached answers are stored 0600. Cluster object names and event text go to the provider unmasked unless the operator passes --anonymize, which is off by default and masks only identifiers.

C9 Audit & traceability

0.00 / 1.00

The CLI keeps no record of what it did: which resources it read, what text it sent to the AI provider, or what came back. The only output is the report on stdout, plus cached answers stored under hashed keys. Debug lines appear only with --verbose and go to stdout. The serve mode, which is not scored, does log each gRPC request with structured zap fields.

C10 Limits & kill switch

0.50 / 1.00

There is no agent loop to run away. Each run makes one completion per detected problem, each OpenAI completion is capped at 2,048 tokens, and Kubernetes concurrency is capped at 100. No limit applies to the number of calls per run or their total cost, and AI and Kubernetes requests use a background context with no timeout. Ctrl-C ends the process, which stops in-flight requests, and nothing keeps running in the background.