"If I Delete This Secret, What Breaks?" — Mapping Blast Radius in Kubernetes

Every Kubernetes operator has felt this moment: you're cleaning up a namespace, your cursor is hovering over kubectl delete secret legacy-db-credentials, and a quiet voice asks — is anything still using this?

The honest answer, with stock tooling, is "I don't know." This article works backward from that question: what would you need to answer it reliably, why kubectl alone can't, and how to get a real answer in minutes with an open-source dependency graph.

Why kubectl can't answer the question

Kubernetes stores resources as independent objects. The relationships between them — a Deployment mounting a ConfigMap, an Ingress routing to a Service, a RoleBinding granting a ServiceAccount access — exist only as references inside spec fields. There is no reverse index. You can ask "what does this Deployment mount?" by reading its spec, but you cannot ask the reverse: "which Deployments mount this ConfigMap?"

The usual workaround is a chain of greps:

kubectl get deployments -o yaml -A | grep -B 20 "legacy-db-credentials"

This misses entire categories of dependents:

The hidden factor most people overlook: the dangerous dependencies are exactly the ones that don't look like dependencies. RBAC bindings and platform-identity links (a ServiceAccount bound to an AWS IAM role via IRSA, for example) almost never show up in a grep, but they're load-bearing.

Working backward: what a real answer looks like

The end goal is a single query: given resource X, show me everything downstream of it, with the paths. That requires three things:

  1. A complete inventory of resources, including CRDs — not just the built-in kinds.
  2. Typed edges between them: mounts, routes-to, binds, scales, owns. The edge type matters because "breaks immediately" (a mounted Secret) and "breaks on next rollout" (an imagePullSecret) are different risks.
  3. A graph you can traverse in both directions, so "what depends on X" is as cheap as "what does X depend on".

This is precisely what KubeAtlas builds: a directed dependency graph of every resource in the cluster — Deployments, ConfigMaps, Services, Ingresses, Gateways, HTTPRoutes, PVCs, RBAC, and CRDs — that you can query through a web UI, an API, or straight from kubectl.

Step 1 — Install KubeAtlas

The fastest path is the in-memory Helm install (no persistence, one binary):

helm install kubeatlas oci://ghcr.io/lithastra/charts/kubeatlas \
  --version 1.3.1 \
  --namespace kubeatlas --create-namespace

kubectl -n kubeatlas rollout status deploy/kubeatlas
kubectl -n kubeatlas port-forward svc/kubeatlas 8080:80

Then open http://localhost:8080. If you'd rather not install anything in the cluster at all, skip to the kubectl atlas option below — it builds the graph client-side.

Security note: KubeAtlas reads every namespace, ConfigMap, and RBAC binding in your cluster, and the default install is deliberately ClusterIP-only with no built-in authentication. Put an auth layer (oauth2-proxy, Pomerium, Cloudflare Access) in front before exposing it. See the security warning in the docs.

Step 2 — Run a blast-radius query

In the web UI, find the Secret (full-text search is ranked across names, kinds, namespaces, and labels), select it, and switch on blast-radius mode. The canvas highlights everything downstream, with two controls that matter:

Edge types are filterable (RBAC / Network / Config / Storage), so you can ask narrower questions like "what does this Secret affect through configuration mounts only?"

Step 3 — Or do it from the terminal

The kubectl atlas plugin renders the same graph without any in-cluster server. It talks to the Kubernetes API directly:

# one resource and its neighborhood
kubectl atlas deployment api -n petclinic

# a whole namespace
kubectl atlas namespace petclinic

# interactive UI, served from an in-process server
kubectl atlas namespace petclinic --local-ui

The default mode writes a static SVG (it needs the graphviz dot binary); --local-ui opens the full interactive UI with no graphviz and no in-cluster components. Install:

curl -L https://github.com/lithastra/kubeatlas/releases/latest/download/kubectl-atlas_$(uname -s)_$(uname -m).tar.gz \
  | tar -xz kubectl-atlas && sudo install kubectl-atlas /usr/local/bin/

Step 4 — Make it a habit, not a heroic effort

Blast-radius checks are most valuable when they happen before every risky change, not just during postmortems. Two ways to systematize:

The owl's-eye summary

QuestionStock kubectlDependency graph
What does X reference?Read the spec, manuallyOne query, typed edges
What references X?Grep and hopeOne query, reverse edges
What breaks transitively?Not answerableBlast-radius mode, any depth
What changed recently?Not answerableTime-axis diff (1h/4h/24h/7d)

The pre-deletion pause shouldn't be a moment of dread. With the graph in place, "if I delete this Secret, what breaks?" becomes a question with an answer — usually in under a minute.