Kubernetes' ConfigMaps and Secrets lesson pointed out that a Secret's base64 value is "encoded, not encrypted" — a specific instance of a much more general confusion that causes real security incidents on a regular basis, once every distinct operation this domain has covered is named clearly and told apart.
3 min read
By this point in the domain, three genuinely different operations have each been covered in depth: hashing (lesson 1, one-way, no key), encryption (lessons 2–3, reversible, requires a key), and — a third operation this domain hasn't named directly yet — encoding. All three transform data from one representation to another, which is exactly why they get confused in casual conversation ("we encode passwords" — a phrase that should raise real alarm, since it usually means something insecure is happening).
Encoding (base64, URL encoding, hex encoding) converts data into a different representation for compatibility reasons — fitting binary data into a text-safe format, for instance — using a fixed, publicly known scheme with no secret key involved anywhere. Anyone can decode base64 back to the original data using nothing but the publicly documented algorithm; there's no key to protect because none exists.
import base64
encoded = base64.b64encode(b"hello") # anyone can reverse this
decoded = base64.b64decode(encoded) # trivially, with zero secret neededThe Kubernetes domain's ConfigMaps and Secrets lesson pointed out that a Secret's stored value is base64-encoded, "which is reversible, not encryption" — anyone with read access can decode it trivially. That specific warning is one concrete instance of this lesson's general point: encoding provides zero confidentiality, by design, because it was never built to provide any. The mistake isn't unique to Kubernetes — "we encoded it" gets treated as a security measure in plenty of real systems, and it never actually is one.
| Operation | Reversible? | Needs a key? | What it actually provides |
|---|---|---|---|
| Encoding | Yes, by anyone | No | Compatibility (safe representation) — no security property at all |
| Hashing | No | No | A fingerprint; verifies data hasn't changed, doesn't hide it |
| Encryption | Yes, with the right key | Yes | Confidentiality — hides content from anyone without the key |
The confusion runs both directions — Auth's password-hashing lesson correctly uses hashing for passwords (a one-way, no-comparison-back operation is exactly what's needed there), but a team reaching for "hashing" when they actually need to retrieve the original value later has made the same category error in the opposite direction: hashing a credit card number for storage, expecting to somehow "unhash" it later to process a refund, is not a viable design at all — that specific need requires encryption (a reversible operation), not hashing.
Before writing or reviewing code that transforms sensitive data, name precisely which of the three operations is actually happening, and confirm it matches the actual goal: hiding structure for compatibility (encoding — provides no security), proving data hasn't changed without needing to recover it (hashing), or protecting confidentiality with the ability to recover the original later given the right key (encryption). A surprising share of real cryptographic bugs — the Kubernetes Secrets gotcha among them — trace back to exactly this three-way confusion, not to any flaw in the underlying primitives this whole domain has covered.
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. Why does base64 encoding provide zero confidentiality?
2. Why would hashing a credit card number for storage be the wrong approach if it needs to be retrieved later?
3. What distinguishes encoding, hashing, and encryption from each other?
Cryptography Fundamentals