Base64 in Kubernetes Secrets

Kubernetes Secrets store values as Base64-encoded strings in YAML. Learn how to encode, decode, and manage secrets , and why Base64 is not encryption.

Base64 in Kubernetes Secrets

Kubernetes Secrets use Base64 so YAML can carry bytes.

Kubernetes Secrets are Base64-encoded, not encrypted. The encoding exists because the YAML specification handles arbitrary byte sequences unreliably; Base64 ensures binary values like TLS keys and database passwords survive YAML parsing intact.1

Base64 encoding in a Kubernetes Secret provides no security. Anyone with read access to the Secret resource can decode the value in seconds. Actual secret protection comes from RBAC policies, etcd encryption at rest, and tools like Sealed Secrets or external secret managers.

Opens the Base64 Text & File Encoder/Decoder with the value from this page already filled in.

Open in the tool →

How Kubernetes Secrets store Base64 values

A Secret manifest stores values under the data field as Base64-encoded strings that survive YAML parsing intact. The corresponding stringData field accepts plain text and Kubernetes encodes it automatically before storing. The two fields are mutually exclusive at the individual key level, so a key in the data field cannot also appear in stringData for the same Secret.1

Reading and decoding Secret values

When you run kubectl get secret mysecret -o jsonpath='{.data.password}', Kubernetes returns the Base64-encoded string; piping to base64 -d recovers the original value without requiring any cluster credentials beyond the developer's existing kubectl access. Consequently, every developer or service account with get permission on the Secret can read the credential without any additional tooling. Furthermore, GitOps workflows that commit Secret manifests to version control expose Base64-encoded values in the repository history; decoding them requires no key. This is why any GitOps pipeline that stores raw Secret manifests in a repository, even a private one, should use a tool like Sealed Secrets or SOPS to encrypt the values before they reach the git history, because a repository leak immediately exposes every credential in plain form.

Reading the value through the same decode step also keeps audit trails honest, because the decoded secret matches exactly what the pod receives at runtime rather than a truncated copy. It also means a reviewer comparing the manifest against the running pod sees the same bytes, which makes unauthorized changes easy to spot in a security review.

Common pitfalls and variants

Newline characters are the single most common source of Kubernetes Secret encoding bugs. echo 'password' | base64 encodes the trailing newline along with the password, so the decoded value becomes password\n instead of just password, which breaks database connections and API key comparisons silently. This bug is especially frustrating because the Secret manifest looks correct in YAML, and the pod starts without error, but every authentication attempt fails at the application layer where the trailing newline is not stripped.2

Avoiding newline and field conflicts

Always use echo -n 'password' | base64 or printf '%s' 'password' | base64 to avoid the trailing newline that corrupts the encoded value. Furthermore, some tools (including Helm) accept stringData and encode automatically, while others require pre-encoded data values. Mixing the two fields in the same Secret causes the data field to override stringData for keys that appear in both. A safer pattern is to standardize on one field across your entire team, preferably stringData for development manifests and pre-encoded data values for production, so that no developer accidentally commits a plaintext credential that gets silently Base64-encoded by Kubernetes.

Security and best practice

Enable etcd encryption at rest using Kubernetes' EncryptionConfiguration with an AES-CBC or AES-GCM provider , this encrypts Secret data on disk in etcd so physical etcd access does not expose secrets.3 Use Sealed Secrets (Bitnami) to commit encrypted secrets to Git: only the cluster's private key can decrypt them. External secret managers (AWS Secrets Manager, HashiCorp Vault, Google Secret Manager) with the External Secrets Operator pull secrets at runtime, keeping no sensitive data in the cluster manifests. Rotate secrets regularly and use separate namespaces to scope RBAC access. Never commit un-encrypted Secret manifests to a public repository, and add a .gitignore rule for any file with a name containing secret or credential to prevent accidental commits during local development.

RBAC scoping to limit Secret access

When you restrict RBAC permissions to only the services that actually need a Secret, you reduce the blast radius if a service account is compromised. The minimum required verbs for a pod that reads a Secret at startup are get on the specific named resource; the list and watch verbs are unnecessary unless the application needs to react to Secret rotation at runtime.4 Define a dedicated ServiceAccount per deployment and bind it to a Role that grants get on only the specific Secret names the deployment uses.

Avoid binding to the secrets resource with a wildcard name match: this grants read access to every Secret in the namespace regardless of your intent. Use the resourceNames field in the Role definition to enumerate exactly which Secret objects the role may read. Auditing RoleBinding and ClusterRoleBinding objects that reference Secrets reveals which service accounts currently hold read access to sensitive credentials across the cluster.

Sealed Secrets and the External Secrets Operator

Sealed Secrets (from Bitnami) encrypts a Kubernetes Secret with the cluster's public key, producing a SealedSecret custom resource that is safe to commit to Git. Only the cluster's private key, held inside the Sealed Secrets controller running in the cluster, can decrypt and re-create the underlying Secret.5 The kubeseal CLI performs the encryption: kubeseal -f yaml < secret.yaml > sealed-secret.yaml, though before any of that, the fastest way to check what a Kubernetes secret actually decodes to is to paste it here, without piping through a terminal you don't fully trust with the output. Teams using GitOps workflows commit the SealedSecret YAML rather than the raw Base64 Secret YAML.

External Secrets Operator for runtime secret injection

The External Secrets Operator (ESO) fetches secret values from an external store at runtime and creates standard Kubernetes Secrets automatically. The Secret value lives in the external store; only a reference to it appears in the cluster manifest. Rotation in the external store propagates to the cluster within the operator's configured refresh interval, eliminating the need to re-apply manifests or restart pods for a credential rotation.6

When to use this

Use Kubernetes Secrets for credentials, API keys, TLS certificates, and any value that should not appear in plain text in a ConfigMap or pod spec. Combine with etcd encryption and RBAC for baseline protection; use an external secret manager for production-grade security.

Examples

Encode a password for a Kubernetes Secret manifest

Before
# Need to store 'my-db-password' in a Secret
After
# Step 1: encode (no trailing newline)
echo -n 'my-db-password' | base64
# Output: bXktZGItcGFzc3dvcmQ=

# Step 2: reference in Secret manifest
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  password: bXktZGItcGFzc3dvcmQ=

Always use echo -n to avoid encoding the trailing newline.

Decode a Secret value with kubectl

Before
kubectl get secret db-secret
After
kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d

Add ; echo after base64 -d to add a newline to the terminal output.

Sources
  1. 1.

    Kubernetes, "Secrets," kubernetes.io, accessed June 2026. https://kubernetes.io/docs/concepts/configuration/secret/

  2. 2.

    The Open Group, "echo," opengroup.org, 2018. https://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html

  3. 3.

    "etcd Encryption at Rest: Configuration, Key Rotation, and Performance Impact," systemshardening.com, accessed June 2026. https://www.systemshardening.com/articles/kubernetes/etcd-encryption/

  4. 4.

    Kubernetes, "Using RBAC Authorization," kubernetes.io, accessed June 2026. https://kubernetes.io/docs/reference/access-authn-authz/rbac/

  5. 5.

    Bitnami, "bitnami-labs/sealed-secrets," github.com, accessed June 2026. https://github.com/bitnami-labs/sealed-secrets

  6. 6.

    External Secrets Operator, "Overview," external-secrets.io, accessed June 2026. https://external-secrets.io/main/introduction/overview/

FAQ

Not by default. Base64 encoding is not encryption. Etcd encryption at rest must be explicitly configured using EncryptionConfiguration. Without it, the encoded values are stored as plain Base64 in etcd and readable by anyone with direct etcd access.

echo 'value' adds a newline before Base64 encoding. Use printf '%s' 'value' | base64 or echo -n 'value' | base64 to exclude the newline. When debugging, pipe to xxd to see the decoded bytes including non-printable characters.

data requires manually Base64-encoded values. stringData accepts plain text and Kubernetes encodes it automatically. stringData is write-only , it does not appear in kubectl get output.

Add **/secrets.yaml to .gitignore. For GitOps workflows, use Sealed Secrets or External Secrets Operator so only encrypted or referenced secrets exist in the repository.

Yes. Paste the value in the encoder to get the Base64 string, or paste an encoded value in the decoder to verify it. CapyToolkit runs entirely in your browser , credentials you paste are never transmitted anywhere.

Additional resources

Guides

Embedding Images as Data URIs in HTML and CSS Learn how to embed images, SVGs, and fonts as Base64 data URIs in HTML attributes and CSS. Includes format, size limits, and when to avoid inlining. Building HTTP Basic Auth Headers with Base64 HTTP Basic Authentication encodes username:password in Base64 for the Authorization header. Learn the format, curl usage, and why HTTPS is required. How JWT Tokens Use Base64url Encoding JWT tokens encode header and payload as Base64url without padding. Learn the structure, how to decode the claims, and why JWTs are not encrypted by default. Base64 in Kubernetes Secrets Kubernetes Secrets store values as Base64-encoded strings in YAML. Learn how to encode, decode, and manage secrets , and why Base64 is not encryption. MIME Email Attachments and Base64 Encoding SMTP email encodes attachments as Base64 in MIME multipart messages. Learn the format, line length rules, charset headers, and common email encoding bugs. Storing Binary Secrets in Environment Variables Environment variables only hold text strings, but Base64 encoding lets you store binary secrets like TLS keys and certificates as env var values. Learn the pattern and risks. Embedding Binary Data in JSON APIs JSON cannot represent raw binary data. Base64 encoding is the standard way to embed images, files, and binary fields in JSON API requests and responses. URL-Safe Base64 vs Standard Base64 URL-safe Base64 replaces + with - and / with _ so strings are safe in URLs, HTTP headers, and filenames. Learn when to use each variant and how to convert between them. SSH Keys and PEM Certificates in Base64 SSH keys, TLS certificates, and PEM files wrap raw binary keys in Base64 between header and footer markers. Learn the format, how to decode keys, and common CI/CD patterns.