Keep the Secrets Off the Disk
I spent years running IT in healthcare, where a leaked credential isn't an "oops"—it's a reportable incident with your name on it. That discipline stuck. So when I started wiring AI tools into everything I run, I brought one rule with me: a secret should never touch the disk.
It sounds absolute because it is. And it's easier to honor than most people think.
Why a File Is the Worst Place for a Secret
The default way to hand a program a credential is to put it in a file. A .env, a config, an exported environment variable. It works on the first try, which is exactly the problem—it works, so nobody ever goes back and questions it.
But a secret in a file is a secret in a dozen places you never intended. It's in your shell history. It's one stray commit from your repo. It's in the backup, in the log line someone added while debugging, in the screenshot attached to a support ticket. You didn't leak it on purpose. You just left it somewhere long enough for the leak to happen on its own.
The fix isn't to guard the file better. It's to not have the file.
Inject at Runtime, Store Nowhere
The pattern I settled on: the secret lives in a vault and gets injected into the process only at the moment it runs. Nothing lands on disk. Nothing survives the process exiting.
When I connected Google Workspace to Claude Code, the integration needed OAuth client credentials—the keys to Gmail, Calendar, and Drive. The obvious move is to drop them in a config file. Instead I wrap the whole thing in the 1Password CLI, which pulls the secrets from a vault and hands them to the process as it starts. The credentials exist in memory for exactly as long as the tool is running, and nowhere else. There's no file to leak, because there's no file.
That's the whole idea, and it generalizes. The vault holds the secret. The runtime borrows it. The disk never sees it.
The Fix Creates a New Problem (It Always Does)
Here's the part nobody warns you about: the secure version breaks things the insecure version didn't, and the breakage looks like a bug in something else.
Wrapping the tool to inject secrets meant every line it printed got masked, so nothing sensitive could slip out through the output. Sensible. Except the OAuth flow needed to print a login URL to the screen, and now that URL came out as a row of asterisks. The security layer was doing its job so well it blocked the exact thing I was trying to do.
The wrong fix is to loosen the masking. The right fix was to route around it: I changed the auth step to open the browser directly instead of printing a URL for me to copy. The masking stays airtight, and the login just works.
The lesson stuck. When a security control blocks a legitimate action, the answer is almost never to weaken the control. It's to find the path that satisfies both.
Least Privilege Is the Same Rule, One Level Up
Keeping secrets off disk is really one instance of a bigger habit I carried out of healthcare: give every part of a system the least it needs, for the least time. In a HIPAA environment that meant role-based access, regular access reviews, and automatic deprovisioning the moment someone left. Same principle, different scale.
A credential injected at runtime has least privilege in the time dimension—it exists only when it's needed and vanishes after. Access that expires on its own is access you never have to remember to revoke. And access you never granted permanently is access nobody can steal later.
The Only Secret You Can't Leak
Every few months there's a story about keys pushed to a public repo, a token in a log, a password in a screenshot. Almost none of them were leaked by an attacker breaking in. They were left in a file that got copied somewhere it shouldn't have gone.
You cannot leak a secret that was never written down. Keep it in the vault, borrow it at runtime, hand it back when you're done. The safest file is the one you never created.