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.
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
# Need to store 'my-db-password' in a Secret
# 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
kubectl get secret db-secret
kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d Add ; echo after base64 -d to add a newline to the terminal output.
- 1.
Kubernetes, "Secrets," kubernetes.io, accessed June 2026. https://kubernetes.io/docs/concepts/configuration/secret/
- 2.
The Open Group, "echo," opengroup.org, 2018. https://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html
- 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.
Kubernetes, "Using RBAC Authorization," kubernetes.io, accessed June 2026. https://kubernetes.io/docs/reference/access-authn-authz/rbac/
- 5.
Bitnami, "bitnami-labs/sealed-secrets," github.com, accessed June 2026. https://github.com/bitnami-labs/sealed-secrets
- 6.
External Secrets Operator, "Overview," external-secrets.io, accessed June 2026. https://external-secrets.io/main/introduction/overview/