Claude Code Kubernetes Secrets (2026)
Managing secrets in Kubernetes is a critical skill for any developer deploying applications to production. Whether you’re handling API keys, database credentials, or TLS certificates, understanding how to manage these sensitive values securely directly impacts your application’s security posture. Claude Code provides several approaches to streamline Kubernetes secrets management, from direct kubectl operations to sophisticated external secrets integrations.
Understanding Kubernetes Native Secrets
Kubernetes has built-in support for secrets through the Secret resource type. You can create secrets manually using kubectl, but this approach has limitations. Base64 encoding isn’t encryption, and storing secrets in plain text within YAML files poses security risks, especially when committing to version control.
Here’s a basic example of creating a secret manually:
kubectl create secret generic db-credentials \
--from-literal=username=admin \
--from-literal=password=securepassword123
This creates a generic secret that can be mounted as environment variables or files within your pods. However, managing secrets this way becomes cumbersome at scale. Each secret must be created individually, and there’s no built-in mechanism for synchronization with external secret management systems.
Secret Types and When to Use Them
Kubernetes defines several built-in secret types, each suited to a specific purpose:
| Type | Use Case | Key Fields |
|---|---|---|
Opaque |
Generic key-value data, most common | Arbitrary |
kubernetes.io/dockerconfigjson |
Private container registry credentials | .dockerconfigjson |
kubernetes.io/tls |
TLS certificates and private keys | tls.crt, tls.key |
kubernetes.io/service-account-token |
Service account API tokens | token, ca.crt |
kubernetes.io/basic-auth |
Username/password pairs | username, password |
kubernetes.io/ssh-auth |
SSH private keys | ssh-privatekey |
Using the correct type matters because Kubernetes validates the required fields and some controllers. like cert-manager and Ingress controllers. specifically look for the kubernetes.io/tls type when mounting certificates.
The Base64 Misconception
A persistent source of confusion is thinking that base64-encoded values in a Secret manifest are protected. They are not. Base64 is an encoding scheme, not encryption. Anyone who can read the Secret object via kubectl or the Kubernetes API can trivially decode the values:
kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 -d
This is why secrets at rest in etcd are a concern. The protection you actually want comes from three places: RBAC restricting who can read Secret objects, encryption at rest for etcd, and avoiding storing secret manifests with actual values in version control.
External Secrets Operator Approach
The External Secrets Operator (ESO) has become the standard solution for Kubernetes secrets management. It synchronizes secrets from external secret stores like AWS Secrets Manager, HashiCorp Vault, or Azure Key Vault into Kubernetes secrets. This approach provides centralized secret management with audit logs and automatic rotation.
To get started with ESO, you install the operator and configure a ClusterSecretStore that points to your external secrets provider. Then you define ExternalSecret resources that specify which secrets to sync:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: api-keys-secret
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
target:
name: api-keys
creationPolicy: Owner
data:
- secretKey: STRIPE_API_KEY
remoteRef:
key: production/stripe
property: api_key
This configuration syncs the Stripe API key from HashiCorp Vault into a Kubernetes secret named api-keys. The refresh interval determines how often the operator checks for secret updates. You can adjust this based on your rotation requirements. more frequent rotations warrant shorter intervals.
Configuring a ClusterSecretStore for AWS Secrets Manager
For teams running on AWS, Secrets Manager is often the most natural external store. Here is a full ClusterSecretStore definition using IAM roles for service accounts (IRSA):
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: aws-secrets-manager
spec:
provider:
aws:
service: SecretsManager
region: us-east-1
auth:
jwt:
serviceAccountRef:
name: external-secrets-sa
namespace: external-secrets
The serviceAccountRef points to a Kubernetes service account that has been annotated with the ARN of an IAM role. That IAM role carries a policy granting secretsmanager:GetSecretValue on the relevant secrets. This keeps AWS credentials out of the cluster entirely. the pod’s projected service account token is exchanged for temporary AWS credentials through the IRSA mechanism.
Configuring for HashiCorp Vault
For HashiCorp Vault, the setup looks similar but uses Vault’s token or Kubernetes auth method:
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: vault-backend
spec:
provider:
vault:
server: "https://vault.internal.example.com"
path: "secret"
version: "v2"
auth:
kubernetes:
mountPath: "kubernetes"
role: "external-secrets"
serviceAccountRef:
name: external-secrets-sa
namespace: external-secrets
Vault’s Kubernetes auth method validates the pod’s service account token against the Kubernetes API to issue a Vault token. This avoids hard-coding Vault tokens in cluster configuration and supports automatic token renewal.
Automating Secrets Management with Claude Code
Claude Code excels at automating repetitive Kubernetes operations. When you describe your secrets architecture in a CLAUDE.md file or system prompt, Claude Code builds up context about which secrets exist in which namespaces, their expected refresh intervals, and the external store paths they map to. This persistent context proves invaluable when debugging issues across multiple environments.
For day-to-day operations, Claude Code can help you:
- Generate secure secret manifests without exposing values
- Validate secret configurations before deployment
- Audit existing secrets across multiple namespaces
- Implement secret rotation procedures
- Write tests that verify secrets are properly mounted and accessible
When working with secrets, always follow the principle of least privilege. Use dedicated service accounts for each application and limit secret access to specific namespaces. Claude Code can generate the appropriate Role and RoleBinding YAML for your applications, ensuring proper isolation between workloads.
Generating RBAC for Secrets
Here is the kind of RBAC scaffolding Claude Code can produce for a typical application that needs to read a specific secret:
apiVersion: v1
kind: ServiceAccount
metadata:
name: payments-app
namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: payments-secret-reader
namespace: production
rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["stripe-keys", "db-credentials"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: payments-secret-reader-binding
namespace: production
subjects:
- kind: ServiceAccount
name: payments-app
namespace: production
roleRef:
kind: Role
name: payments-secret-reader
apiGroup: rbac.authorization.k8s.io
Scoping the Role to specific resourceNames ensures the payments application can only read the two secrets it legitimately needs, not every secret in the namespace. Claude Code can generate this scaffolding quickly if you provide the application name, namespace, and list of required secrets.
Best Practices for Production Environments
Production environments require stricter secrets management. Never commit actual secret values to version control. Instead, commit only the ExternalSecret definitions that describe which secrets to pull from your external store and how to map them into the cluster.
Consider these security measures:
- Enable encryption at rest for etcd to protect secrets at storage level
- Use pod security policies (or their replacement, Pod Security Admission) to restrict secret access based on workload requirements
- Implement network policies that limit which pods can access secrets
- Enable audit logging for all secret operations for compliance and forensic analysis
- Scan your CI pipeline for secret values accidentally committed to manifests
Encryption at Rest
Kubernetes supports envelope encryption for secrets at rest in etcd. You configure this through the EncryptionConfiguration API on the API server:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-32-byte-key>
- identity: {}
Managed Kubernetes services like EKS, GKE, and AKS offer envelope encryption through their respective KMS integrations, which is generally easier to manage than a self-hosted key. Enable this on new clusters before you start storing secrets. retroactively encrypting existing secrets requires rewriting them.
Detecting Secrets in Version Control
Before any manifest is committed, run a scanner. Tools like detect-secrets or trufflehog can be configured as pre-commit hooks:
.pre-commit-config.yaml
repos:
- repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
hooks:
- id: detect-secrets
args: ['--baseline', '.secrets.baseline']
This catches the common case of a developer accidentally pasting a real credential into a manifest during testing.
Handling Secret Rotation
Rotation is one of the most challenging aspects of secrets management. External Secrets Operator simplifies this by automatically updating Kubernetes secrets when the underlying external secrets change. Set appropriate refresh intervals based on your rotation policies. for highly sensitive credentials, consider hourly refreshes.
For manual rotations, create a clear runbook that Claude Code can help execute:
Update secret in external store first, then sync
kubectl get secret api-keys -o yaml > backup-secret.yaml
kubectl apply -f external-secret-definition.yaml
Verify new secret is available
kubectl get secret api-keys -o jsonpath='{.data.STRIPE_API_KEY}' | base64 -d
Always maintain backups before performing rotations, and test your rollback procedures in a staging environment before touching production.
Zero-Downtime Rotation
The trickiest part of rotation is that running pods hold the old secret value in their environment variables until they restart. File mounts are updated in place by kubelet (with a small delay), but environment variables are not. For database password rotations, this means:
- Add the new password to the database (the database now accepts both old and new)
- Update the secret in your external store
- Wait for ESO to sync the new value to the Kubernetes Secret
- Trigger a rolling restart of the affected deployment
- Once all pods are running on the new password, remove the old password from the database
After verifying the new secret is synced
kubectl rollout restart deployment/payments-app -n production
kubectl rollout status deployment/payments-app -n production
The rolling restart replaces pods gradually, so the application stays available throughout the rotation. New pods get the new password; old pods keep running with the old one until the rollout completes. This is only safe if the database accepts both passwords simultaneously, which is why step 1 comes before updating the secret.
ESO Refresh vs. Force Sync
ESO syncs on the interval you specify plus any time an ExternalSecret is applied or modified. If you need to force an immediate sync outside the normal schedule, delete and recreate the Kubernetes Secret. ESO will recreate it immediately from the external store:
kubectl delete secret api-keys -n production
ESO recreates it within seconds
kubectl get secret api-keys -n production
This is useful after a manual rotation where you don’t want to wait for the next scheduled refresh.
Advanced Patterns
Secret Templating
For complex deployments, consider implementing secret templating. This allows you to define a single ExternalSecret that generates multiple Kubernetes secrets with different formats based on the consuming application’s requirements:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: database-secret
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: ClusterSecretStore
target:
name: database-credentials
template:
engineVersion: v2
data:
# Some apps want a connection URL
DATABASE_URL: "postgresql://{{ .username }}:{{ .password }}@{{ .host }}:5432/{{ .dbname }}"
# Others want individual components
DB_HOST: "{{ .host }}"
DB_USER: "{{ .username }}"
DB_PASS: "{{ .password }}"
data:
- secretKey: username
remoteRef:
key: production/database
property: username
- secretKey: password
remoteRef:
key: production/database
property: password
- secretKey: host
remoteRef:
key: production/database
property: host
- secretKey: dbname
remoteRef:
key: production/database
property: dbname
Templating handles both scenarios. applications that expect a single DATABASE_URL and legacy applications that need individual components. without storing duplicate data in Vault.
TLS Certificates with cert-manager and ESO
Another advanced pattern involves using secret references in Ingress resources for TLS certificates. Combine the External Secrets Operator with cert-manager to automatically provision and renew TLS certificates from Let’s Encrypt or your internal certificate authority:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: app-tls
namespace: production
spec:
secretName: app-tls-cert
dnsNames:
- app.example.com
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
cert-manager creates and rotates the secret app-tls-cert. Your Ingress resource then references it:
spec:
tls:
- hosts:
- app.example.com
secretName: app-tls-cert
This keeps certificate management fully automated. no manual renewals, no expiry alerts to chase down.
Multi-Cluster Secret Distribution
For organizations running multiple Kubernetes clusters, distributing secrets consistently is a challenge. One approach uses a central Vault cluster as the single source of truth, with each Kubernetes cluster running ESO configured to pull from the same Vault paths. This means a rotation in Vault propagates to all clusters automatically within the configured refresh interval.
Alternatively, tools like Argo CD can manage ExternalSecret definitions across clusters through GitOps, ensuring the secret configuration (not the values) is consistent everywhere.
Conclusion
Kubernetes secrets management requires careful planning and the right tooling. Combined with the External Secrets Operator, you have a solid framework for managing sensitive data across your clusters. Start with namespace isolation, implement external secrets storage, and automate rotation workflows to maintain strong security without sacrificing developer productivity.
The path to production-grade secrets management follows a natural progression: replace manually created secrets with ExternalSecrets, enable etcd encryption, implement RBAC scoped to specific secret names, add pre-commit scanning, and finally automate rotation with zero-downtime procedures. Each step is independently valuable, so you can improve incrementally rather than attempting a complete overhaul at once.
By following these practices and using Claude Code to generate YAML scaffolding and rotation runbooks, you can establish a secrets management workflow that scales with your infrastructure while maintaining security best practices appropriate for production workloads.
Try it: Paste your error into our Error Diagnostic for an instant fix.
Related Reading
- Chrome Enterprise Bandwidth Management: A Practical Guide
- Chrome Enterprise Certificate Management: A Practical Guide
- Chrome Enterprise Extension Management API: A Practical.
Built by theluckystrike. More at zovo.one
Find the right skill → Browse 155+ skills in our Skill Finder.