Kubernetes Secrets look like a solution to credential sprawl, but the default implementation solves almost none of the problems that matter. A Secret object stores values as base64 strings inside etcd, Kubernetes' cluster data store — base64 is an encoding, not encryption, so anyone with etcd read access or a valid kubectl get secret -o yaml permission can decode a database password in one command. In 2018, attackers found Tesla's Kubernetes dashboard exposed without authentication on the public internet and used AWS credentials sitting in a pod's environment variables to run a cryptomining operation inside Tesla's own cloud account. Six years later, GitGuardian's 2024 State of Secrets Sprawl report counted 12.8 million secrets leaked on public GitHub in 2023 alone, a 28% jump from 2022, with a large share coming from committed Kubernetes manifests and Helm values files. Securing secrets in Kubernetes means treating the built-in Secret object as a distribution mechanism, not a vault, and layering encryption, RBAC, and rotation around it.
Are Kubernetes Secrets actually encrypted by default?
No — Kubernetes Secrets are base64-encoded, not encrypted, and etcd stores them in plaintext unless you explicitly enable encryption at rest. Base64 is reversible with a single echo <value> | base64 -d command, so it provides zero confidentiality against anyone who can read the etcd data directory, an etcd snapshot, or a cluster backup. To fix this, operators must pass --encryption-provider-config to kube-apiserver and define an EncryptionConfiguration resource that specifies a provider such as aescbc, secretbox, or kms. Kubernetes' KMS v2 provider went generally available in Kubernetes 1.29 (released December 2023), adding envelope encryption with a cached data-encryption key so every read no longer requires a round trip to the external key management service. Without any of this configured — which is still the out-of-the-box state on most managed clusters — a stolen etcd backup file is functionally equivalent to a plaintext credentials dump.
How do attackers typically get access to Kubernetes Secrets?
Attackers rarely break Kubernetes' cryptography; they walk through three doors that are usually left unlocked: over-permissive RBAC, exposed cluster endpoints, and auto-mounted service account tokens. A Role or ClusterRole granting get, list, or watch on the secrets resource — often bundled into a broad edit or admin binding for convenience — hands any compromised pod or CI runner read access to every Secret in that namespace. CVE-2020-8563 is a concrete example of the second door: kube-controller-manager and kube-scheduler logged cloud-provider credentials in cleartext at verbosity level 4 or higher, a defect fixed in Kubernetes 1.15.5, 1.16.2, and 1.17.0. The third door narrowed considerably in Kubernetes 1.24 (April 2022), when the project stopped auto-generating long-lived service account token Secrets in favor of short-lived, audience-bound tokens issued via the TokenRequest API — but clusters still running older manifests, or workloads that mount tokens unnecessarily, remain exposed.
What's the difference between native Kubernetes Secrets and an external secrets manager?
Native Secrets store data inside the cluster; external managers store it outside the cluster and inject it at runtime, which limits how much an attacker gains from compromising any single cluster. HashiCorp Vault, AWS Secrets Manager, and Azure Key Vault are the three most common backends, and two integration patterns dominate. The External Secrets Operator (ESO) — which supports more than 20 backend providers as of its 2024 releases — watches an ExternalSecret custom resource and syncs values from the external store into a native Kubernetes Secret, keeping RBAC on the Secret object as the last line of defense. The Secrets Store CSI Driver skips that step entirely, mounting credentials as files directly into a pod's volume so no Kubernetes Secret object is ever created in etcd. For GitOps workflows, Bitnami's Sealed Secrets takes a third approach: it encrypts secrets client-side with a public key so the ciphertext is safe to commit to Git, and only the in-cluster controller holding the private key can decrypt it.
How often should Kubernetes Secrets be rotated?
Most security teams rotate service-facing credentials — database passwords, API keys, TLS certificates — every 30 to 90 days, and immediately after any suspected exposure, contractor offboarding, or leaked CI/CD token. Static, hand-created Secrets that never expire are the norm on most clusters, which is exactly the gap the CIS Kubernetes Benchmark's secrets management section (control family 5.4) targets by recommending external secret storage over long-lived, manually managed Secret objects. Vault addresses this with dynamic secrets: a database credential can be issued with a one-hour lease that Vault automatically revokes, so a leaked value stops working within 60 minutes instead of remaining valid indefinitely. cert-manager, the de facto standard for TLS in Kubernetes, defaults to renewing certificates 15 days before expiry and writing the renewed certificate into a Secret automatically, removing rotation from the list of things a human has to remember.
Why does mounting Secrets as environment variables increase risk?
Environment variables are exposed through channels that volume-mounted files are not, including crash dumps, /proc/<pid>/environ, child-process inheritance, and debug logging. A Node.js process that logs process.env in an unhandled-exception handler, or a JVM that writes a heap dump to disk during an out-of-memory event, will capture every environment-variable Secret in plaintext in whatever artifact gets shipped to a log aggregator or crash-reporting service. Files mounted from a Secret volume are not inherited by child processes and are far less likely to end up in a diagnostic dump by accident. This is precisely why CIS Kubernetes Benchmark control 5.4.1 recommends consuming Secrets as mounted files rather than environment variables — a one-line change in a pod spec that removes an entire class of accidental-exposure paths.
How Safeguard Helps
Safeguard reduces Kubernetes secrets risk at the points where it actually gets exploited: manifests, images, and running clusters. Reachability analysis confirms whether a package or component flagged by a scanner is actually loaded and callable in your deployed workload, so teams stop burning rotation and remediation cycles on secrets-handling libraries that never execute in production. Griffin AI triages exposed-secret and misconfiguration findings from SBOMs and Kubernetes manifests, ranking a hardcoded database credential in a Helm values file above a theoretical RBAC over-grant with no attached workload. Safeguard generates and ingests SBOMs across container images and cluster resources to maintain a live inventory of where secrets-adjacent dependencies live, and its auto-fix PRs can convert an environment-variable Secret reference to a volume mount or swap a static credential for an External Secrets Operator reference — closing the gap before it reaches production.