Securing Your Secrets: Best Practices for API Key Management in the Cloud
I'm going to start with an embarrassing admission. In my first weeks of using AI to build with, I leaked API keys twice. Not on GitHub. Not in a public repo. Both times in the chat conversation with the AI itself.
I'd been pasting code snippets into Claude AI's chat to ask for help, not noticing that the snippet I copied still had a real API key hardcoded in it. Both times I caught it within minutes. Both times I had to rotate the key, audit my usage logs, and verify nothing weird had happened in the meantime.
Nothing bad happened, but the lesson stuck. AI chat conversations get logged, get scanned, and aren't private. Treating them like a private notebook is exactly the wrong mental model. Two key rotations in two weeks taught me a workflow I now apply to every project: keys never leave your local environment in plaintext.
What This Post Covers
The secrets management workflow I use across every project, why .env files plus .gitignore is the foundation, where production secrets actually live (hint: not in your code), the specific mistake that almost cost me thousands, and the quiet discipline that prevents most key-leak scenarios entirely.
The .env File Pattern
The foundation of secrets management is a single rule: API keys live in .env files, and .env files never get committed to Git.
An .env file is just a plain text file at the root of your project that holds environment variables:
Your code reads these values via environment variables instead of hardcoding them. In Python, that's os.getenv("ANTHROPIC_API_KEY"). In Node, it's process.env.ANTHROPIC_API_KEY. The actual secrets sit in the .env file. The code only references them by name.
The critical companion to the .env file is the .gitignore file:
This tells Git to never track these files. They stay on your local machine and your production server, but they never end up in your repository. The actual code in the repo references the secrets by name; the secret values themselves never leave the environments where they're needed.
Production Secrets Live in the Platform
Local .env files solve the development problem. Production needs a different solution because there's no .env file to read from when your code runs on a server you might not even SSH into.
Every modern hosting platform has a "secrets" or "environment variables" section in its dashboard. This is where production secrets actually live.
For my Cloudflare Pages projects (frontend code), environment variables go in the Pages dashboard. They're available at build time and runtime, encrypted at rest, never visible in logs. When Cloudflare builds my project, it injects the values where my code expects to find them. The repo never sees them.
For my Oracle VPS backends, environment variables live in .env files on the server itself, deployed there once and protected by file permissions. The GitHub Actions workflow that deploys updates uses GitHub Secrets — another encrypted-at-rest store — to authenticate the SSH connection without ever exposing the key.
The pattern is the same across platforms: the secrets exist in encrypted vaults provided by each platform, your code references them by name, and the actual values never appear in your repository or your terminal history.
The AI Chat Mistake
This is the part I haven't seen written about enough. Every guide talks about not committing keys to GitHub. Almost no guide talks about not pasting them into AI conversations.
The failure mode is simple. You're debugging something. You copy a chunk of code from your editor and paste it into Claude AI to ask "why is this not working?" The code happens to contain a hardcoded API key because you were testing locally and hadn't refactored to environment variables yet. The chat now has your key in it.
AI conversations get logged on the platform. Some are stored for safety review. Some get included in usage analytics. Some get fed back into training pipelines (depending on the platform's policies). Even when those policies forbid using your data for training, the data still exists somewhere on someone's server. You're not the only person who can read what you typed.
This happened to me twice in my first weeks of building with AI. Both times I noticed within minutes because I have a habit of re-reading my own messages after sending them. Both times I rotated the leaked key immediately and checked the API usage logs to make sure nothing weird had happened.
What I do differently now: before pasting any code into an AI chat, scan it for anything that looks like a key. Anything that starts with sk-, anything that's a long random string, anything assigned to a variable with "secret" or "key" or "token" in its name. If I see one, replace it with a placeholder before pasting:
The AI doesn't need to see the actual key value to help you debug. It needs to see the structure of your code. Replace the secret with a placeholder, paste, get help, copy back the suggested fix into your editor where the real .env reference still works.
Rotation Without Tears
If you do leak a key — and most builders eventually will, even with good practices — rotation is the recovery move. Done quickly, it limits damage. Done correctly, it becomes routine instead of stressful.
Every API platform that issues keys also lets you rotate them. The pattern is universal: log into the platform, generate a new key, update your .env file with the new value, deploy the updated config to your environments, then revoke the old key. The whole process takes maybe ten minutes if you've done it before.
The only friction point is updating multiple environments. Local .env file, Cloudflare Pages dashboard, Oracle VPS server, GitHub Secrets if applicable — all of them need the new key, and the old key needs to keep working until they're all updated. The trick is to update the new key everywhere first, verify everything works, then revoke the old key. Don't revoke first; you'll cause an outage during the transition.
I rotate keys preemptively now, every few months, even when nothing's been leaked. It keeps the rotation process familiar instead of scary, and it limits the window any specific key is active. If a key did leak six months ago and I never noticed, the rotation already neutralized it.
The .env.example Convention
One small pattern that keeps secrets management sustainable: commit a .env.example file to the repo, even though the real .env stays local.
The .env.example file documents what environment variables the project needs without exposing any actual values. When someone (including future you) clones the repo to a new machine, they can copy .env.example to .env and fill in the real values. No guessing what variables are required. No missing keys causing confusing runtime errors.
This sounds like a tiny thing. It's the difference between "I onboarded a new project setup in 5 minutes" and "I spent 30 minutes hunting through code to figure out which environment variables it needs."
The Quiet Discipline
The thing that prevents most key leaks isn't any specific tool. It's a habit of noticing.
Before committing: glance at the diff. If you see anything that looks like a real secret, stop and fix it. If you can't tell whether something's a real secret, treat it as one and fix it.
Before pasting into any AI chat: scan the code mentally for keys. The pattern recognition gets fast with practice. Long random strings, anything starting with sk- or pk_, anything explicitly labeled as a secret — flag them, replace them, then paste.
Before sharing code with anyone (PR review, Discord help thread, screenshot for a tweet): same scan. Public spaces are obviously dangerous, but private DMs and AI chats are still places where keys can end up logged.
This isn't paranoia. It's the equivalent of looking both ways before crossing the street. The five seconds it takes to scan the code prevents the five hours it would take to clean up after a leak.
Where to Start
If you've been building without thinking about secrets, here's the entry path. Pull up your most recent project. Check whether any API keys, database URLs, or tokens are hardcoded in the code itself. If yes, you have work to do.
Create a .env file at the project root. Move every hardcoded secret to it. Add .env to your .gitignore. Update your code to read from environment variables instead of hardcoded values. Test that everything still works locally.
For production, move the secrets to your hosting platform's environment variables section. Cloudflare Pages, Vercel, Railway, your VPS — all of them have a place for this. Update the production deployment to read from those instead of any committed config.
Once that baseline is in place, the AI chat discipline becomes a habit. The .env.example file becomes muscle memory. Key rotation becomes a 10-minute task instead of a panic. The whole secrets management practice becomes invisible most of the time, exactly because it's working.
What's Next
Secrets management is one piece of the operational layer. The next post in this series goes back to building — specifically, how Claude's Artifacts feature changes the prototyping workflow. Building UI components in conversation, then exporting working code — the speed difference for non-developers is hard to overstate until you've used it.
← Previous: Automating the Deployment Pipeline Next: The Power of Claude's Artifacts →
More posts in this series will cover the actual stack — Artifacts, database strategy, monitoring, and the workflows that hold everything together. If you're working on shipping something with AI tools and have questions, drop them in the comments — the more we share, the faster we all move.
Disclaimer: This blog documents practical development workflows based on personal experience. Nothing here is financial, legal, or professional advice.
Comments
Post a Comment