Kubernetes Secrets look encrypted. They are base64-encoded, stored in etcd, and gated behind RBAC — but by default, none of that adds up to real protection. Base64 is an encoding scheme, not encryption, and etcd stores Secret data in plaintext unless you explicitly turn on encryption at rest. In February 2018, RedLock researchers found an unauthenticated Kubernetes dashboard belonging to Tesla, pulled AWS access credentials out of a pod's environment variables, and used them to mine cryptocurrency inside Tesla's AWS account. Since then, at least four distinct CVEs — CVE-2022-4886, CVE-2023-5043, CVE-2023-5044, and CVE-2023-2728 — have given attackers direct or indirect paths to Secret data inside clusters. Red Hat's 2023 State of Kubernetes Security survey found that 90% of respondents had experienced a security incident in their Kubernetes environment in the prior 12 months, and exposed sensitive data was the misconfiguration teams worried about most, at 32%. This guide breaks down where the exposure actually comes from and how to close it.
Why aren't Kubernetes Secrets secure by default?
Kubernetes Secrets aren't secure by default because the API only base64-encodes them before writing them to etcd, and etcd does not encrypt data at rest unless an administrator configures an EncryptionConfiguration resource. Kubernetes introduced encryption-at-rest support for the API server as an alpha feature back in version 1.7 (2017), but it has never been the default — clusters must opt in by defining a provider such as aescbc, secretbox, or a KMS plugin, and pointing the API server at it with --encryption-provider-config. Without that step, anyone who can read etcd directly, take an etcd snapshot, or run kubectl get secret -o yaml with sufficient RBAC permissions gets the plaintext value with one base64 -d command. Managed Kubernetes offerings (EKS, GKE, AKS) now offer envelope encryption via cloud KMS, but it's typically an opt-in setting at cluster creation, not a retroactive one — enabling it later requires re-writing every existing Secret to force re-encryption.
What real-world incidents have stemmed from Kubernetes secrets exposure?
Real-world incidents range from an exposed dashboard leaking cloud credentials to admission-controller bugs that let attackers pull Secrets they were never authorized to see. The 2018 Tesla case is the canonical example: a Kubernetes dashboard with no authentication exposed pod details, one of which contained AWS credentials with access to an S3 bucket holding vehicle telemetry data. More recently, CVE-2022-4886, CVE-2023-5043, and CVE-2023-5044, disclosed between late 2022 and October 2023, are a trio of ingress-nginx path-sanitization and annotation-injection flaws that let an attacker with Ingress-object permissions retrieve Secrets stored anywhere in the cluster, including the ingress controller's own TLS credentials. Separately, CVE-2023-2728 (CVSS 6.5, disclosed June 2023) let a workload using ephemeral containers bypass the ServiceAccount admission plugin's mountable-secrets policy, retrieving Secrets the pod's service account was never granted access to reference. None of these required a zero-day in etcd itself — they exploited the gap between what a policy intended to allow and what the API server actually enforced.
Which RBAC misconfigurations let attackers read Secrets they shouldn't?
The most common RBAC misconfiguration is granting get, list, or watch on the secrets resource at the cluster scope to roles that only need namespace-level or read-only access. Kubernetes maintainers were concerned enough about this that the built-in view ClusterRole was hardened years ago specifically because bindings to it were exposing Secret contents to users who only expected to see Pods, Deployments, and ConfigMaps — but plenty of custom roles, Helm chart defaults, and CI/CD service accounts still copy the older, broader pattern. A ClusterRoleBinding that attaches a secrets-readable role to a system:authenticated or system:serviceaccounts group effectively hands every workload identity in the cluster the ability to read every Secret in every namespace. This is why the NSA/CISA Kubernetes Hardening Guide explicitly recommends auditing every RoleBinding and ClusterRoleBinding that references the secrets resource — in Red Hat's 2023 survey, misconfiguration was cited as the leading cause of security issues by 59% of respondents, ahead of runtime attacks (32%) and known vulnerabilities (31%).
How did CVE-2024-9486 show the risk of hardcoded default credentials?
CVE-2024-9486 showed that even infrastructure-provisioning tooling can leak the credentials that protect a cluster's Secrets. Disclosed in October 2024, the flaw affects Kubernetes Image Builder versions up to and including v0.1.37: VM images built with the Proxmox provider shipped with a static, publicly known builder account password that was never disabled after the image build completed. Any node deployed from an affected image could be logged into remotely with that default credential and used to gain root — and root on a node means read access to every kubelet-mounted Secret and volume on that host, plus the node's own service account token. It carried a CVSS score of 9.8 (critical) precisely because it required no cluster misconfiguration at all — the exposure was baked into the golden image before a single workload was ever deployed. The fix, shipped in v0.1.38, disables the builder account at the end of the build and randomizes its password during the process; the interim mitigation was to manually run usermod -L builder on every affected node.
What are the most common ways Kubernetes Secrets leak outside the cluster boundary?
The most common leak path isn't a cluster attack at all — it's a Secret value that never should have left the manifest in the first place. Teams routinely commit values.yaml files or raw Secret manifests containing plaintext credentials to Git repositories, mount Secrets as environment variables that then get written to application logs or crash dumps, or bake API keys into container image layers during docker build where they persist in the image history even after being "removed" in a later layer. CI/CD pipelines compound this: a build job that exports a Secret to an environment variable for a kubectl apply step often has that variable readable in build logs or by any other job sharing the same runner. Helm's default behavior of storing full manifest history — including Secret values — as Secrets themselves in the kube-system or release namespace adds another copy of the same sensitive data that's easy to forget is there.
How can security teams detect and remediate Kubernetes secrets vulnerabilities before attackers do?
Teams detect and remediate Kubernetes secrets risk by combining static scanning of manifests and Helm charts, encryption at rest with an external KMS provider, and RBAC audits that flag any role with cluster-wide access to the secrets resource. Practical steps, in priority order: enable API server encryption at rest with a cloud KMS or HashiCorp Vault transit backend rather than the built-in aescbc provider (which stores its key on local disk); replace long-lived Secret objects with a tool like External Secrets Operator or the Vault Agent Injector so credentials are fetched at pod startup and never persisted in etcd at all; run kubectl auth can-i --list --as=system:serviceaccount:<ns>:<sa> against every service account to find over-broad secrets permissions; and scan Git history and container image layers for hardcoded credentials before they ship, not after. Rotation matters too — a Secret that can't be rotated within minutes of a suspected leak is a liability regardless of how it's stored.
How Safeguard Helps
Safeguard maps the full path from a vulnerable dependency or exposed Secret to the workload that actually calls it, using reachability analysis to tell your team which flagged CVEs — like the ingress-nginx or ServiceAccount bypass issues above — are exploitable in your specific deployment versus theoretical noise in a scan report. Griffin AI, Safeguard's agentic triage engine, correlates RBAC bindings, manifest scans, and runtime signals to prioritize the Secrets exposure that's actually reachable from an untrusted entry point, rather than surfacing every secrets-readable role in the cluster with equal urgency. Safeguard generates and ingests SBOMs across your container images and Helm charts so you have a live inventory of what's deployed and where credentials are mounted, and it opens auto-fix pull requests that tighten RBAC bindings, pin patched image versions, or move hardcoded values into a proper secrets backend — so remediation ships as fast as the finding does.