On this page
  1. What is a Kubernetes Secret?
  2. Are Kubernetes Secrets encrypted?
  3. How do I make Secrets safer?
  4. Should I use an external secrets manager instead?
  5. Where AI coding assistants get this wrong
  6. Checklist
  7. FAQ
    1. Is base64 the same as encryption?
    2. What is encryption at rest for Secrets?
    3. How do I rotate a leaked secret safely?
  8. Related topics
  9. Sources
concept

Are Kubernetes Secrets Actually Secret?

A Kubernetes Secret is base64-encoded, not encrypted, and readable by anyone with get on Secrets. Learn what it does and does not protect, and how to harden it.

Quick answer

  • A Kubernetes Secret is base64-encoded, which is a transfer encoding, not encryption — anyone with read access sees the plaintext.
  • Secrets are stored unencrypted in the API datastore unless you explicitly enable encryption at rest.
  • Being a Secret mainly keeps values out of pod specs and limits which identities can read them via RBAC.
  • Encrypt at rest, restrict Secret reads, avoid mounting secrets as environment variables, and prefer an external secret manager.
  • A secret that reached a Git repository, a container image, or a log is compromised regardless of how it is stored later.

What is a Kubernetes Secret?

A Secret is an API object that holds a small amount of sensitive data — a password, a token, a certificate — so it can be injected into pods separately from the application image. It is the right place for credentials, as opposed to a ConfigMap or a hardcoded value. But its name overpromises: the object exists to organize and control access to the value, not to make it cryptographically unreadable.

Are Kubernetes Secrets encrypted?

Not by default. Values are stored base64-encoded in the API server’s datastore, which anyone can decode, and encryption at rest is an opt-in configuration of the API server. Without it, an operator with access to the datastore, or a backup of it, reads every Secret in the cluster. With it, the values are encrypted on disk — but anything with get permission on the Secret object still retrieves the plaintext through the API, because that is what a Secret is for.

How do I make Secrets safer?

Four changes cover most of the gap. Enable encryption at rest in the API server configuration. Use RBAC to restrict get and list on Secrets to only the service accounts that need them, since read access is total. Prefer mounting a Secret as a file over injecting it as an environment variable, because environment variables leak into logs, crash dumps, and child processes. And rotate anything that has been exposed — encryption does not help a credential that is already out.

Should I use an external secrets manager instead?

For anything beyond a hobby cluster, yes. An external manager — a cloud secret store, Vault, or an operator that syncs from one — keeps the authoritative value outside the cluster, gives you rotation and audit logging, and shrinks what a cluster compromise exposes. The cluster then holds short-lived synced copies rather than the source of truth. This matters most for the credentials your AI assistant was most likely to paste into a manifest in the first place.

Where this bites vibecoders

The vibecoder failure is trusting the word ‘Secret’. An assistant generates a Secret manifest with a base64 value, commits it to Git because the manifest has to live somewhere, and treats the problem as solved. In reality the value is in version control in a trivially reversible encoding, readable by anyone with repository access forever, and the cluster stores it unencrypted. The right handling keeps the plaintext out of the repository entirely — a reference to an external store or a value injected at deploy time — which is the opposite of what generated manifests tend to do.

Where AI coding assistants get this wrong

  • Committing Secret manifests with real values to Git, assuming base64 is protection.
  • Assuming Secrets are encrypted at rest without enabling it.
  • Injecting secrets as environment variables, where they leak into logs and process listings.
  • Granting broad get and list on Secrets to make a workload work.
  • Storing credentials in ConfigMaps or the image because the app ‘just needed it’.
  • Never rotating a secret that has appeared in a repository or a log.

Checklist

  • Never commit real Secret values; keep them out of Git entirely.
  • Enable encryption at rest for the API datastore.
  • Restrict Secret reads to the service accounts that need them.
  • Mount secrets as files rather than environment variables where possible.
  • Use an external secrets manager for anything important.
  • Rotate any credential that has been committed, logged, or exposed.

FAQ

Is base64 the same as encryption?

No. Base64 is an encoding that represents binary data as text and is reversible by anyone with the string. Encryption requires a key and is not reversible without it. A base64-encoded Secret provides no confidentiality.

What is encryption at rest for Secrets?

An API server configuration that encrypts Secret data before writing it to the datastore. It protects against someone reading the database or its backups directly. It does not change what a client with get permission retrieves through the API.

How do I rotate a leaked secret safely?

Issue the new credential, update every consumer, verify the new value works, then revoke the old one — in that order, so there is no window without a valid credential. If it was committed to Git, removing it from history is necessary but not sufficient: rotate regardless.

Sources

Share: