Build an AI Kubernetes Secret Rotation Assistant with Claude API
Secret rotation gets skipped because nobody wants to be the one who breaks production by rotating a credential something still depends on. Build a tool that maps secret usage across your cluster and safely sequences rotation with Claude API.
Secret rotation policy exists on paper everywhere and gets executed almost nowhere, because the real risk isn't rotating the secret — it's not knowing everything that reads it, and finding out the hard way when a service starts failing auth mid-rotation. This tool maps actual secret consumption before proposing a rotation sequence, so "what depends on this" stops being a guess.
Setup
pip install anthropic kubernetesSecret Usage Mapper
import anthropic
from kubernetes import client, config
client_ai = anthropic.Anthropic()
def find_secret_consumers(secret_name: str, namespace: str) -> dict:
"""Find every workload that references this secret — as an env var,
a mounted volume, or an imagePullSecret."""
config.load_kube_config()
v1 = client.CoreV1Api()
apps_v1 = client.AppsV1Api()
consumers = {"deployments": [], "statefulsets": [], "cronjobs": [], "service_accounts": []}
for deploy in apps_v1.list_namespaced_deployment(namespace).items:
if references_secret(deploy.spec.template.spec, secret_name):
consumers["deployments"].append(deploy.metadata.name)
for sts in apps_v1.list_namespaced_stateful_set(namespace).items:
if references_secret(sts.spec.template.spec, secret_name):
consumers["statefulsets"].append(sts.metadata.name)
for sa in v1.list_namespaced_service_account(namespace).items:
if sa.secrets and any(s.name == secret_name for s in sa.secrets):
consumers["service_accounts"].append(sa.metadata.name)
return consumers
def references_secret(pod_spec, secret_name: str) -> bool:
for container in pod_spec.containers:
for env in (container.env or []):
if env.value_from and env.value_from.secret_key_ref and env.value_from.secret_key_ref.name == secret_name:
return True
for volume in (pod_spec.volumes or []):
if volume.secret and volume.secret.secret_name == secret_name:
return True
return FalseExternal Consumer Detection
def check_external_references(secret_name: str, namespace: str) -> list[str]:
"""Secrets referenced from outside the cluster (CI systems pulling
from Vault-synced secrets, external services reading via API) are
the ones that break rotation silently — check what you can."""
warnings = []
# Check for external-secrets operator syncing this from a source
result = subprocess.run(
["kubectl", "get", "externalsecret", "-n", namespace, "-o", "json"],
capture_output=True, text=True
)
import json
for es in json.loads(result.stdout).get("items", []):
if es["spec"]["target"]["name"] == secret_name:
warnings.append(f"Synced by ExternalSecret from {es['spec']['secretStoreRef']['name']} — rotation must originate at the source, not the K8s secret")
return warningsRotation Plan Generation
PLAN_PROMPT = """Generate a safe rotation plan for this Kubernetes secret.
Secret: {secret_name} in namespace {namespace}
Known in-cluster consumers: {consumers}
External sync warnings: {external_warnings}
Generate a step-by-step rotation plan that avoids downtime:
1. Whether this credential type supports dual validity (old and new both
work simultaneously during a grace period) — most API keys and OAuth
secrets do, most database passwords do NOT unless you create a second
user first
2. The safe order of operations: create new credential -> update secret
with BOTH old and new (if dual-validity) or a rolling restart sequence
(if not) -> verify consumers healthy -> revoke old credential
3. Specific kubectl commands for restarting each consumer type to pick
up the new secret (Deployments don't auto-restart on Secret change
unless using something like Reloader)
4. Rollback plan if a consumer fails to authenticate with the new credential
Respond as a step-by-step runbook."""
def generate_rotation_plan(secret_name: str, namespace: str, consumers: dict, external_warnings: list) -> str:
response = client_ai.messages.create(
model="claude-sonnet-5",
max_tokens=2000,
messages=[{
"role": "user",
"content": PLAN_PROMPT.format(
secret_name=secret_name, namespace=namespace,
consumers=consumers, external_warnings=external_warnings,
)
}]
)
return response.content[0].textExample Output
Rotation Plan: database-credentials (namespace: production)
Consumers found:
- Deployments: api-server, worker-pool, report-generator
- StatefulSets: none
- External: none detected
Credential type: PostgreSQL password — does NOT support dual validity
by default (single password per user).
Safe rotation sequence:
1. Create a second Postgres role with identical grants: `CREATE ROLE
app_user_v2 WITH PASSWORD 'new-password' LOGIN;` then grant it the
same permissions as the current role
2. Update the Kubernetes secret with the NEW role's credentials
3. Rolling-restart consumers one at a time, verifying health before
proceeding: `kubectl rollout restart deployment/api-server -n production`
then `kubectl rollout status deployment/api-server -n production`
4. Repeat for worker-pool, then report-generator
5. Once all 3 consumers confirmed healthy on the new credential
(check logs for auth errors), revoke the OLD role:
`DROP ROLE app_user_v1;`
Rollback: if any consumer fails auth after restart, revert the secret
to the old credential and restart that consumer immediately — the old
role remains valid until step 5, so this is a safe rollback window.
Why the Dual-Validity Check Matters Most
The single most common rotation failure is treating every credential type the same — API keys often support having two valid keys simultaneously (rotate calmly), while a database password swap is often instant and all-or-nothing (requires careful sequencing or a second user). Getting this distinction wrong is what turns a routine rotation into an incident. This is the one judgment call worth having an LLM reason through explicitly rather than applying a generic rotation script to every secret type uniformly.
More AI security tooling? Read our Build AI secret scanner with Claude API and Build AI compliance auditor with Claude API.
Today I Fixed
Short real fixes from production — posted daily
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
AI Agents for Zero-Trust Policy Generation: Where This Is Heading in 2026
Writing least-privilege IAM policies and NetworkPolicies by hand means either over-permissioning out of laziness or spending hours tracing what a service actually calls. AI agents that observe real traffic and generate tight zero-trust policies from it are becoming a practical alternative in 2026.
Build an AI Kubernetes Deployment Readiness Checker with Claude API
Build a Python CLI tool using Claude API that analyzes Kubernetes YAML manifests before deployment — catches missing resource limits, root containers, and security issues with a go/no-go score.
Build an AI Kubernetes Admission Controller with Claude API and OPA
Combine OPA Gatekeeper's policy enforcement with Claude API's reasoning to catch risky Kubernetes manifests that static rules miss — and explain the violation in plain English instead of a cryptic denial message.