CoursesKubernetes fundamentalsConfiguring your app

Secrets: handling passwords

Like config, but sensitive.

Beginner8 min · lesson 15 of 24
In plain terms
A Secret is that settings sheet for passwords — kept aside and handled with care, though by default it’s only folded shut, not truly locked.

Sensitive settings — database passwords, API keys, TLS certificates — need the same "outside the image" treatment as regular config, but with more care. Secrets are Kubernetes’ object for holding this sensitive data, and they work much like ConfigMaps with one crucial difference in intent and handling.

Like config, but sensitive

A Secret holds key-value data just like a ConfigMap and is injected the same ways — as environment variables or as files mounted into the pod. You use it for anything sensitive: a database password, a third-party API key, a certificate. Your app reads it exactly as it would a config value, so from the application’s point of view nothing special is needed. The reason to use a Secret rather than a ConfigMap for these is that Secrets are the object type Kubernetes treats as sensitive — it avoids printing their values in most output, can restrict which nodes receive them, and the cluster’s security controls (access rules, encryption) are built around protecting Secrets specifically. So the rule is simple: non-sensitive settings go in ConfigMaps, sensitive ones go in Secrets, and both keep the values out of your image.

a Secret used by a pod
apiVersion: v1
kind: Secret
type: Opaque
data:
DB_PASSWORD: c3VwZXJzZWNyZXQ= # base64-encoded (see the warning below)
---
spec:
containers:
- name: web
image: my-app:1.4
env:
- name: DB_PASSWORD
valueFrom: { secretKeyRef: { name: db-secret, key: DB_PASSWORD } }
# Create from the command line without hand-encoding:
# kubectl create secret generic db-secret --from-literal=DB_PASSWORD=supersecret

The one thing beginners must understand

Here is the important caveat: by default, the values in a Secret are only base64-encoded, which is not encryption — base64 is trivially reversible, so anyone who can read the Secret can decode the value in one command. A Secret is the right place for sensitive data, but "it is a Secret" does not by itself make it safe. Real protection comes from the controls around it, which you will learn properly later: restricting who is allowed to read Secrets (so not everyone can), and turning on encryption of the cluster’s data store so the values are genuinely encrypted at rest. For now, the beginner takeaways are three: put sensitive values in Secrets (not ConfigMaps or the image), do not commit Secret files with real values into public places, and understand that base64 is encoding for convenience, not a security boundary. Handled with those in mind, Secrets are how your app gets the passwords and keys it needs at runtime without ever baking them into the container image — which is exactly what you want.

Secrets vs ConfigMaps
same as ConfigMaps
key-value data
injected as env vars or files
keeps values out of the image
read at runtime
the difference
for sensitive data
passwords, keys, certs
base64 ≠ encryption
protect via access rules + encryption
Secrets are ConfigMaps for sensitive data — but base64 is not encryption. Real safety comes from restricting who can read them and encrypting the data store.
base64 is not encryption — a Secret is only as safe as its access controls
The values in a Secret are base64-encoded by default, which anyone can decode instantly — so a Secret is not automatically protected. Do not treat "it is in a Secret" as security: keep Secret files with real values out of public repos, and rely on the cluster controls you will learn later (restricting who can read Secrets, and encrypting the data store) for actual protection.