Skip to main content
Welcome to this lesson on managing sensitive data with Kubernetes Secrets.
A presentation slide titled "Kubernetes Secrets" with a dark curved panel on the right displaying a locked folder icon. The left side is mostly white with a small "© Copyright KodeKloud" notice in the corner.

Overview

Kubernetes Secrets provide a way to store and manage sensitive information such as passwords, tokens, and keys. Unlike ConfigMaps (which store plain-text configuration), Secrets store values as base64-encoded data. Remember: base64 is only encoding, not encryption — apply RBAC, encryption at rest, and external KMS integrations for production workloads.
Kubernetes Secrets store values as base64-encoded data. This encoding hides values from casual viewing but is not strong encryption. Use encryption at rest and appropriate RBAC policies for production.

Example application: what not to do

Below is a simple Python Flask app that connects to MySQL. The database hostname, username, and password are hardcoded — which is insecure and not recommended.

Move non-sensitive configuration to ConfigMaps

ConfigMaps are suitable for non-sensitive values (hostnames, feature flags). Do not store credentials here in production. Example ConfigMap (declarative):
Note: The DB_Password above should not be stored in a ConfigMap — shown here only for contrast. Secrets vs ConfigMaps (quick comparison)

Creating Secrets

Two common workflows:
  • Imperative: kubectl create secret from literals or files.
  • Declarative: apply a YAML Secret manifest where data is base64-encoded.
Imperative creation from key/value pairs:
Create a Secret from a file (file contents become the secret value):

Declarative creation requires base64-encoded values

Convert values to base64 on a Linux/macOS host:
Secret manifest with encoded values:
Apply the YAML (you can use either kubectl create -f or kubectl apply -f):

Inspecting Secrets

List secrets:
Example output:
Describe a secret (shows metadata and key sizes, not raw values):
Example output excerpt:
Get the Secret YAML (values remain base64-encoded):
Decode base64 back to plain text:
(Adjust the decode flag for your platform: GNU coreutils use --decode or -d; macOS may use -D.)

Injecting Secrets into Pods

Secrets can be exposed to containers in two common ways:
  1. Environment variables (single keys or all keys at once).
  2. Mounted as files via a secret volume (each key becomes a file with the decoded content).
Example: inject all Secret keys as environment variables using envFrom:
Each key in app-secret becomes an environment variable inside the container (e.g., DB_Host, DB_User, DB_Password). Example: mount the Secret as files inside a volume:
When mounted as a volume, each key becomes a file in the mount directory:
Quick reference table

Best practices and security considerations

  • Do not store plaintext credentials in ConfigMaps.
  • Treat base64 as encoding, not encryption—enable encryption at rest for Secrets on the cluster.
  • Restrict Secrets access using RBAC policies.
  • Consider integrating with an external secrets manager (HashiCorp Vault, AWS KMS/GCP KMS/Azure Key Vault) for higher assurance.
Remember: base64 encoding is not encryption. For production workloads, enable encryption at rest for Secrets, restrict access via RBAC, and consider integrating with an external secrets manager or KMS for better security.
Links and references

Watch Video

Practice Lab