k8s5 min readKubernetes Secrets Management: 12 Mistakes That Expose Your Cluster (and How to Fix Them)Learn the 12 most critical Kubernetes secrets management mistakes that expose production clusters to attacks, and follow concrete fixes with RBAC, encryption, and External Secrets Operator examples.ShieldOps Team2026-06-15 ·4Kubernetes secrets are not actually secret. By default, they are stored as base64-encoded plain text in etcd, accessible to anyone with API server access, visible in pod specs, and often committed to Git repositories by accident. For a platform built to manage containerized workloads at scale, this is a surprising gap — and it is one of the most common attack vectors in Kubernetes environments today.In this guide, we cover twelve specific Kubernetes secrets management mistakes that teams make in production, and the exact fixes that close each gap. If you are running workloads on Kubernetes and storing any sensitive data — API keys, database passwords, TLS certificates, or cloud credentials — these practices apply to your cluster right now.Why Kubernetes Secrets Management Matters More Than EverKubernetes has become the default orchestration platform for containerized applications, with over 5 million clusters running globally according to recent CNCF surveys. Every one of these clusters uses secrets of some kind. Yet the default Kubernetes secrets implementation leaves most of the security work to the cluster operator.High-profile breaches in the last two years consistently traced back to exposed Kubernetes secrets: a cloud provider credential stored in a ConfigMap, a database password committed to a public Helm chart, a service account token with cluster-admin privileges leaked through a pod's environment variables. In every case, the technology was not the problem; the secrets management practice was.Because of the shared nature of Kubernetes clusters, a single exposed secret can compromise every workload on that cluster. If an attacker gains access to a secret with cross-namespace permissions, they can pivot from a low-priority application to a production database within minutes. Treating secrets as first-class security objects, not as afterthoughts in a YAML file, is the single highest-leverage security investment you can make in your Kubernetes environment.Mistake 1: Treating Base64 as EncryptionThe most dangerous misconception in Kubernetes secrets management is assuming that base64 encoding is encryption. It is not. Base64 is encoding, trivially reversible by anyone with access to the encoded string. Runningecho 'cGFzc3dvcmQ=' | base64 -d takes less than a second. The fix:Enable encryption at rest for etcd. This is the single most impactful change you can make.# Create an encryption configuration file apiVersion: apiserver.config.k8s.io/v1 kind: EncryptionConfiguration resources: - resources: [secrets] providers: - aesgcm: keys: - name: key1 secret: $(openssl rand -base64 32) - identity: {} Pass this configuration to the API server using the--encryption-provider-config flag. Once enabled, all secrets are encrypted at rest in etcd using AES-GCM or AES-CBC. Without this, anyone with direct etcd access — including backup administrators — can read every secret in your cluster. Kubernetes has supported encryption at rest since v1.7, yet a surprising number of production clusters still run without it. Check yours today withkubectl get --raw /api/v1/namespaces/kube-system/configmaps/encryption-config. Mistake 2: Not Restricting Access to Secrets via RBACBy default, any authenticated user or service account can list and read secrets in namespaces they have access to. This means a compromised CI/CD runner, a misconfigured monitoring agent, or even a developer's local kubeconfig can expose every secret in a namespace.The fix:Apply least-privilege RBAC for secrets access explicitly.apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: production name: secret-reader rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: namespace: production name: app-secret-reader subjects: - kind: ServiceAccount name: my-app roleRef: kind: Role name: secret-reader Never grantlist or watch permissions on secrets unless a specific use case requires it. The difference between get and list is significant: list returns all secrets in a namespace, while get requires the caller to know the exact secret name. Restrict create, update, and delete permissions to cluster administrators only. Mistake 3: Storing Secrets in Environment Variables Without EncryptionPassing secrets to pods via environment variables is convenient, but it leaks secrets into the pod spec, which is visible to anyone withkubectl describe pod access, in audit logs, and often in monitoring dashboards. The fix:Mount secrets as volumes instead of environment variables where possible, and always use encryption at rest.apiVersion: v1 kind: Pod metadata: name: secure-app spec: containers: - name: app image: myapp:latest volumeMounts: - name: db-credentials mountPath: /etc/credentials readOnly: true volumes: - name: db-credentials secret: secretName: db-secret When you mount secrets as volumes, the data is available only inside the running container and is not exposed through the Kubernetes API after the pod is created. Combined with read-only filesystems and non-root containers, this significantly limits the blast radius of a compromised pod.Mistake 4: Committing Secrets to Git RepositoriesCommitting Kubernetes secret manifests to version control is one of the most widespread security anti-patterns. Once a secret is in Git, it is there forever, even if you delete it in a later commit. Services like GitHub's secret scanning can detect some exposures, but the damage is often already done.The fix:Use a GitOps workflow with sealed secrets or an external secrets operator.# Create a SealedSecret kubeseal --format yaml < secret.yaml > sealed-secret.yaml # Commit and deploy the SealedSecret git add sealed-secret.yaml git commit -m "Add production database secrets" git push SealedSecrets are encrypted by a controller in your cluster and can be safely committed to public or private repositories. Only the cluster running the Sealed Secrets controller can decrypt them.For more advanced use cases, theExternal Secrets Operatorintegrates with cloud secret managers like AWS Secrets Manager, GCP Secret Manager, and HashiCorp Vault.Mistake 5: Hardcoding Service Account Tokens in Pod SpecsKubernetes automatically mounts a service account token into every pod. By default, this token is bound to the pod's service account and mounts at/var/run/secrets/kubernetes.io/serviceaccount/token. Attackers who compromise a pod can exfiltrate this token and use it to make API calls with the service account's permissions. The fix:Disable automatic token mounting and use projected volumes with time-bound tokens.apiVersion: v1 kind: Pod metadata: name: secure-pod spec: automountServiceAccountToken: false containers: - name: app image: myapp:latest If your application needs to make API calls, mount a projected volume with a time-bound, audience-restricted token:projected: sources: - serviceAccountToken: path: token expirationSeconds: 3600 audience: kubernetes This approach ensures that tokens are short-lived and scoped to specific audiences, drastically reducing the window of exposure if a token is compromised.Mistake 6: Storing Secrets in ConfigMapsConfigMaps are not designed for sensitive data. They are stored in plain text in etcd, visible through the Kubernetes API, and often logged. Despite this, teams sometimes store credentials in ConfigMaps because they treat all configuration data the same way.The fix:Always usekind: Secret for sensitive data, never ConfigMap. Enable encryption at rest for secrets. If you need to manage large volumes of secrets, use an external secrets manager with the External Secrets Operator or a dedicated secrets store CSI driver. Mistake 7: Using Namespace-Wide Service Accounts with ClusterRole BindingsA service account bound to a ClusterRole with broad permissions can access secrets across all namespaces. If a pod using this service account is compromised, the attacker has immediate access to every namespace's secrets.The fix:Use namespace-scoped service accounts with specific Roles. Audit all ClusterRoleBindings regularly and remove any that grant unnecessary cross-namespace access to secrets.kubectl get clusterrolebindings -o wide | grep -i secret kubectl describe clusterrolebinding Know exactly which service accounts have cross-namespace secret access and why.Mistake 8: Not Rotating Secrets RegularlySecrets that never rotate become more valuable over time. A credential that was valid when the application was deployed may still be valid years later, long after the original key should have been retired. Kubernetes Secrets do not automatically rotate, so this is entirely on the operator.The fix:Implement automated secret rotation using the External Secrets Operator or a reconciliation loop.apiVersion: external-secrets.io/v1beta1 kind: SecretStore metadata: name: aws-secrets-manager spec: provider: aws: service: SecretsManager region: us-east-1 --- apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: db-credentials spec: refreshInterval: 24h secretStoreRef: name: aws-secrets-manager target: name: db-secret data: - secretKey: password remoteRef: key: production/db/password SetrefreshInterval to match your security policy for secret rotation. When the value changes in the external manager, the External Secret is updated automatically, and you can trigger pod reloads using tools like Reloader or Stakater. Mistake 9: Logging Secrets in Application LogsApplications often log environment variables or configuration data during startup, which frequently includes secrets. These logs end up in centralized logging systems, SIEM tools, and sometimes public log aggregation services.The fix:Implement secret scrubbing in your logging pipeline. Use structured logging and explicitly exclude sensitive fields. For Kubernetes audit logs, ensure that theaudit-log-maxbackup and audit-log-maxage flags are configured to limit exposure. For Falcoruntime security rules, add alerts for processes that read secret files and write to stdout.Mistake 10: Relying on Default Kubernetes Secrets Without External IntegrationThe built-in Kubernetes Secret resource is functional but limited. It lacks automatic rotation, audit trails for secret access, integration with cloud secret stores, and fine-grained access policies beyond RBAC. For production environments, relying solely on native Secrets is a significant gap.The fix:Integrate Kubernetes Secrets with an enterprise secret management platform. TheExternal Secrets Operatorbridges Kubernetes Secrets with AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, and HashiCorp Vault. For Vault specifically, the Vault Agent Injector can inject secrets directly into pods without them ever being stored in Kubernetes Secrets at all.Mistake 11: Exposing Secrets Through Third-Party Helm ChartsPublic Helm charts for popular tools often include default values with placeholder secrets or, worse, documented examples showing how to pass sensitive data directly in values files that get committed to Git.The fix:Audit all Helm charts for secret handling before deploying. Override default values with your secrets management approach. Use a GitOps tool like ArgoCD or Flux that integrates with SealedSecrets or External Secrets to avoid plain-text secrets in your Git repository.Mistake 12: Not Having an Incident Response Plan for Secret ExposureWhen a secret is compromised — and it will happen — teams without a plan waste critical hours deciding what to do. The longer a compromised secret remains valid, the more damage an attacker can do.The fix:Create a documented incident response plan for secret exposure that includes:Immediate revocation of the exposed secretRotation of all secrets that share the same access scopeAudit log review to determine the blast radiusNotification to affected teams and stakeholdersPost-mortem to identify the root cause and prevent recurrenceAutomated tools can help: configure the External Secrets Operator to rotate secrets on-demand, useKubernetes Pod Security Standardsto prevent privileged containers that could exfiltrate secrets, and run regular penetration tests that include secret extraction scenarios.Kubernetes Secrets Management ChecklistUse this checklist to audit your current secrets management posture:⬜ Encryption at rest is enabled for etcd secrets⬜ RBAC restricts secret access to only what each workload needs⬜ Secrets are mounted as volumes, not environment variables⬜ No secrets are committed to Git repositories⬜ Automatic service account token mounting is disabled where not needed⬜ Service account tokens use projected volumes with short expiration⬜ ConfigMaps do not contain sensitive data⬜ Secrets are rotated at regular intervals⬜ External Secrets Operator or equivalent is integrated for production⬜ Application logs are scrubbed of sensitive data⬜ Helm charts are audited for secret handling before deployment⬜ Incident response plan for secret exposure exists and is testedFrequently Asked QuestionsAre Kubernetes Secrets secure by default?No. By default, Kubernetes Secrets are stored as base64-encoded plain text in etcd. They are not encrypted at rest, and access control depends entirely on RBAC configuration, which is often misconfigured.What is the difference between a Secret and a ConfigMap?Both store key-value pairs, but Secrets are intended for sensitive data. The key differences are: Secrets support encryption at rest, have different RBAC verbs, and use base64 encoding (not plain text) in manifests. However, Secrets are not more secure than ConfigMaps unless you enable encryption at rest and proper RBAC.Should I use HashiCorp Vault or cloud-native secret managers with Kubernetes?Both approaches work well. HashiCorp Vault offers rich policy and audit capabilities. Cloud-native options like AWS Secrets Manager, GCP Secret Manager, and Azure Key Vault integrate tightly with their respective ecosystems. The External Secrets Operator supports all of them and provides a consistent Kubernetes-native API.How often should Kubernetes secrets be rotated?Industry best practice recommends every 90 days for static credentials and immediately upon any suspected compromise. For service account tokens, use short-lived tokens with expiration measured in hours, not days.Can SealedSecrets replace a dedicated secret management platform?SealedSecrets are excellent for GitOps workflows because they allow secrets to be committed to Git safely. However, they do not provide automatic rotation, audit logging, or integration with external secret stores. They are a strong layer in your strategy, but not a complete replacement for a dedicated secret management platform.ConclusionKubernetes secrets management is not a single tool or configuration. It is a practice that spans encryption, access control, rotation, auditing, and incident response. The twelve mistakes in this guide are common because the defaults are permissive and the configuration surface is large, but each one has a straightforward fix.Start with the highest-impact changes: enable encryption at rest for etcd, audit your RBAC for secrets access, and stop mounting secrets as environment variables. Then add SealedSecrets or External Secrets Operator to your GitOps pipeline. Finally, automate rotation and build an incident response plan for the inevitable exposure event.If you are unsure where your current Kubernetes secrets management stands, start with an audit of who can access which secrets in your cluster today. That single exercise will tell you exactly which of these twelve mistakes exist in your environment, and those are the ones to fix first.Ready to apply these concepts?Scan your Kubernetes manifests for RBAC gaps, policy issues, and misconfigurations.Scan Your Kubernetes ClusterRelated PostsKyverno vs OPA Gatekeeper: Which Kubernetes Admission Controller Should You Use?2026-06-15Kubernetes Pod Security in 2026: From Privileged Pods to Zero-Trust Workloads2026-06-03Kubernetes Cost Optimization Security Tradeoff Secrets2026-05-30Your takeRate this article or leave a commentShare Submit commentHave more questions? Check ourFAQ