TL;DR: An environment variable holds a long-lived secret that every process can read, cannot be revoked without a deploy, and leaves no record of who used it. A secrets manager issues credentials on demand with a lease, revokes them centrally, and logs every access. Dynamic secrets are the feature worth the migration.
How to approach it
Push past encryption at rest immediately, because that is the answer everyone gives and it is the smallest benefit. The three properties that matter are lifetime, revocation and audit. Then describe dynamic secrets concretely, since that is the capability people have usually only read about.
A strong answer
What is actually wrong with a secret in an environment variable or a CI secret store: it was created once and lives until somebody remembers to change it, which in practice is never. Every process in the container can read /proc/self/environ. It appears in crash dumps and in logs when something prints the environment. Rotating it means changing it in the store and redeploying every consumer, in the right order, which is why nobody does it. And there is no record of which service read it or when, so after a compromise you cannot tell what was exposed.
A secrets manager changes the shape of each of those.
Static secrets with versioning and access control. The baseline: a key-value store where a path has a policy saying which identities can read it, versions so a bad write can be rolled back, and an audit log of every read. Better than a file, still a long-lived secret.
Dynamic secrets, which is the actual argument. Vault connects to your database as an administrator, and when a service asks for credentials Vault creates a brand new database user with a 30-minute lease and hands it over. When the lease expires, Vault deletes the user. Nothing long-lived exists. If a service is compromised, the credentials it held stop working in half an hour without anyone doing anything, and revoking them immediately is one API call. The same pattern covers cloud IAM credentials, SSH certificates and PKI.
Authentication without a bootstrap secret. The obvious objection is that the service needs a credential to talk to Vault, so what has changed? The answer is workload identity: it authenticates with something it already has, a Kubernetes service account token, a cloud instance identity, or an OIDC token from the CI system. Vault verifies that with the platform, so there is no secret zero sitting in a file.
Encryption as a service. The transit engine encrypts and decrypts data on request without releasing the key, so an application can protect fields without ever holding key material.
The practical caveat worth raising unprompted: Vault becomes a hard dependency on your startup path. If it is unavailable, services that need a credential at boot cannot start. So it needs to be highly available, and applications should cache a lease and renew it rather than fetching on every use. Running Vault as a single instance is trading one risk for another.
What interviewers probe next
"What is the unseal problem?" Vault starts sealed and its master key is split into shares held by different people. Auto-unseal with a cloud KMS is how this is done in practice, because a restart at 3am that needs three humans is not an operational plan.
"Where does Kubernetes fit?" The agent injector or the Secrets Store CSI driver puts secrets into the pod as files, and the pod authenticates with its service account. Files are better than environment variables here because they can be updated in place when a lease renews.
"Is a cloud provider's secrets manager enough?" Often yes, and simpler. AWS Secrets Manager and its equivalents cover static secrets with rotation well. The reason to pick Vault is dynamic secrets across several platforms and a single policy model spanning clouds.
Common mistakes
Selling it on encryption, when the value is lifetime, revocation and audit.
Fetching a secret once at startup and holding it forever, which discards the lease model entirely.
Reading from Vault on every request rather than caching the lease, making Vault a latency and availability dependency on the hot path.
Ignoring that Vault is now in the critical path for startup, and running one instance.