The secrets threat model & secret-zero
Sprawl, standing privilege, blast radius, and the bootstrap-trust problem.
Advanced secrets management starts with a threat model, not a tool. Before you reach for Vault or a cloud secrets manager, you have to be able to answer three questions precisely: what counts as a secret, every place a given secret comes to rest or passes through, and who the adversary is at each of those places. Most breaches are not broken cryptography — they are a secret sitting somewhere nobody was defending, read by an identity nobody was scoping. The whole discipline is shrinking the set of places secrets live and the window in which any one of them is valid.
The four states every secret passes through
A secret is exposed differently in each of four states, and a real design defends all four. At rest it lives in storage — etcd, a state file, a backup, a KMS. In transit it crosses the network — hopefully inside TLS, but often also inside a CI log or an error message. In use it is decrypted in process memory, readable by anything that can inspect the process. And in the audit trail it leaves a record of who read it and when — which is itself sensitive. Defending only "at rest" (the part encryption products advertise) leaves the other three wide open.
Sprawl, standing privilege, and blast radius
Three properties predict how bad a leak will be. Sprawl is the number of independent copies of a secret — every copy is an attack surface and a thing you must find and rotate. Standing privilege is how long a credential stays valid and how much it can do while nobody is using it; a database password that is valid for a year and grants full access has enormous standing privilege. Blast radius is what one compromised secret unlocks — a scoped, read-only, one-database credential has a small radius; a shared "app" password reused across services has a huge one.
Secret-zero: the bootstrap-trust problem
Every secrets system has a chicken-and-egg problem at the very start: to fetch secrets, a workload must first authenticate to the secrets manager — but authenticating requires a credential, which is itself a secret. That first credential is "secret-zero." If you solve it by shipping a static token in an environment variable or a Kubernetes Secret, you have not removed the problem, you have just renamed it: that token now has the standing privilege to read everything, and it lives in exactly the places this lesson is about.
# a secret in an env var is readable by anything local:$ cat /proc/$(pgrep -f myapp)/environ | tr "\0" "\n" | grep -i tokenAPP_DB_PASSWORD=s3cr3t-shared-prod# and it follows the process into crash dumps, child processes, and# any log line that dumps the environment on error. env vars are not a vault.