Safeguard
Security Guides•

Kubernetes Secrets and base64: myth vs fact

Base64 in a Secret manifest is encoding, not encryption. Five common beliefs about Kubernetes Secrets, checked against the official guidance.

Safeguard Security Team
3 min read

A Kubernetes Secret is not secret just because its values are base64 encoded. Base64 is an encoding that anyone can reverse. Secrets are also stored unencrypted in etcd by default, and several common permissions expose their contents. Here are five beliefs, each checked against the official guidance.

Myth 1: base64 hides the value

Fact: the Kubernetes Secrets good practices page says a manifest with base64 encoded data exposes the Secret to anyone who can read the file, including anyone with access to the source repository, and that base64 provides no confidentiality. Do not commit Secret manifests with real values.

You can decode a value with one command, so treat the encoded text as the secret itself.

Myth 2: Secrets are encrypted in the cluster

Fact: they are stored unencrypted in etcd by default. Encryption at rest must be configured, and existing Secrets have to be rewritten after you enable it. Details are in Are Kubernetes Secrets encrypted by default.

Myth 3: list access is harmless

Fact: the docs say list implicitly exposes Secret contents. Watch does too. Restrict list and watch to the most privileged, system-level components, and grant get only when normal behavior requires it. Humans should have limited access, including read-only.

Myth 4: no Secret permission means no access

Fact: anyone who can create a pod that uses a Secret can read its value, even without direct read permission. The guide suggests short-lived Secrets, auditing for patterns such as one user reading many Secrets at once, and separate namespaces to isolate access.

Myth 5: every container in a pod needs the Secret

Fact: in multi-container pods, define mounts or environment variables so only the containers that need a Secret can see it. And your application must not log Secret values in plain text or send them to untrusted parties.

What to do instead

  • Enable encryption at rest.
  • Keep real values out of Git. Use an external store where it fits. The docs point to the Secrets Store CSI Driver, which lets the kubelet fetch Secrets from external stores and mount them into authorized pods.
  • Keep RBAC tight.
  • Rotate anything that has appeared in a repository, logs or a ticket.

Whatever you use, add a pipeline check for committed credentials, and rotate any value that has been exposed.

A simple test for your team

Pick one Secret in a non-production namespace and ask three questions. Who can read it through RBAC, including by creating a pod? Is it encrypted at rest in etcd? Does a copy of its value exist in Git history, a chat message or a ticket? If any answer is unclear, you have found your first task.

Quick check

Is a sealed or encrypted manifest safe to commit?

That depends on the tool and key custody, which these sources do not cover. Plain base64 is not safe.

Does an environment variable protect a Secret better than a file?

The fetched guidance does not rank them. Either way, limit which containers receive it and never log it.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.