
๐ค Ghostwritten by Claude Opus 4.6 ยท Curated by Tom Hundley
A .env file is a simple text file that holds your secret keys and passwords outside your actual code โ like a locked drawer next to your desk instead of taping your house key to the front door. If you're building with AI tools and you don't have one set up, your API keys are probably sitting in your code right now, one click away from being public. Today we fix that.
In 2022, a security researcher at GitGuardian reported that over 10 million new secrets (API keys, passwords, tokens) were exposed in public GitHub repositories in a single year โ up 67% from the year before. These aren't big companies making mistakes. Many of them are solo builders who didn't know their code was public, or didn't realize their Stripe key was embedded on line 14 of their app.
I've seen it happen to a vibe coder building a SaaS with Bolt. They pushed their project to GitHub to show a friend. Their OpenAI API key was sitting right in the code. Within 48 hours, someone had racked up over $1,200 in API charges. OpenAI flagged it and shut down the key, but the money was gone. This happens constantly.
Let's make sure it never happens to you.
TL;DR: A .env file is a private notecard where your app looks up secret keys, so the secrets never live inside your actual code.
Imagine you run a small shop. You need a code to open the safe every morning. You have two choices:
A .env file is your wallet. Your code is the store window.
Here's what a .env file actually looks like. It's embarrassingly simple:
OPENAI_API_KEY=sk-abc123yourrealkeyhere
STRIPE_SECRET_KEY=sk_live_xyz789yourstripekeyhere
DATABASE_URL=postgresql://user:password@localhost:5432/mydbThat's it. Each line has a name (like OPENAI_API_KEY), an equals sign, and the secret value. No quotes needed. No fancy formatting.
Your code then reads from this file instead of having the key typed directly in. So instead of this dangerous code:
const apiKey = "sk-abc123yourrealkeyhere";You write this safe code:
const apiKey = process.env.OPENAI_API_KEY;The key point: the .env file stays on your machine. It never gets uploaded, shared, or published. Your code just says "go check the notecard" every time it needs a secret.
TL;DR: Once a secret hits a Git repository โ even for a second โ bots can find it within minutes, and deleting it later doesn't actually remove it from history.
Git (the version tracking system behind GitHub, GitLab, and most code-sharing tools) keeps a complete history of every change you've ever made. If you accidentally include your API key in your code, push it to GitHub, then delete it and push again โ the key is still in the history. Anyone can scroll back and find it.
According to GitGuardian's 2024 State of Secrets Sprawl report, the average time for an exposed secret to be discovered by automated scanning bots is under 24 hours. Attackers run scripts that constantly monitor public repositories for patterns like sk-, AKIA (AWS keys), and other known key formats.
Here's what can happen depending on which key gets exposed:
| Exposed Key | What an Attacker Can Do | Real Consequence |
|---|---|---|
| OpenAI API Key | Run thousands of API calls on your account | Hundreds or thousands of dollars in charges |
| Stripe Secret Key | Issue refunds, access customer payment data | Financial loss, legal liability |
| Database URL | Read, modify, or delete all your data | Complete data breach |
| AWS Access Key | Spin up servers, mine cryptocurrency | Bills in the tens of thousands |
| SendGrid/Email Key | Send spam from your domain | Domain blacklisted, reputation destroyed |
This isn't theoretical. Every one of these scenarios happens regularly to real people.
TL;DR: Every major platform handles environment variables slightly differently โ here's exactly how to set them up in Cursor, Replit, and Vercel.
.env (yes, it starts with a dot โ that's important, it means "hidden file")OPENAI_API_KEY=sk-yourkey.gitignore (or open it if it already exists).gitignore: .envThat .gitignore step is non-negotiable. Without it, your .env file gets uploaded with everything else.
Replit has a built-in secrets manager โ don't use a .env file directly.
OPENAI_API_KEY) and the valueprocess.env.OPENAI_API_KEY (JavaScript) or os.environ['OPENAI_API_KEY'] (Python)Replit's secrets are encrypted and never visible in your code files. This is one of the safest setups for beginners.
Vercel injects these variables at build time. Your deployed app can read them, but they're never visible in your codebase.
TL;DR: If you're building anything that connects to a paid API, a database, or a third-party service, secrets management isn't optional โ it's the first thing you set up.
The three rules of environment variable security are:
That third point is important. When you're building on your laptop, you might use a test Stripe key. When your app goes live, it uses the real Stripe key. Environment variables let you swap these out without changing a single line of code.
TL;DR: Stop reading and do these four things before you build anything else today.
Open every project you're working on. Search all your files for any line containing sk-, sk_live, key=, password=, or token=. If you find actual secret values in your code โ not process.env.SOMETHING, but actual keys โ you have a problem.
Create a .env file in each project and move every secret value into it.
Open (or create) your .gitignore file and add these lines:
.env
.env.local
.env.productionPaste this into Cursor, Bolt, or your AI coding tool the next time you start a project:
I'm starting a new project that will use the following external services: [list your services, e.g., OpenAI, Stripe, Supabase].
Please:
1. Create a .env.example file showing the variable names I need (with placeholder values, not real keys)
2. Create or update .gitignore to exclude .env files
3. Set up the code to read all API keys and secrets from environment variables using process.env
4. Never hardcode any secret values directly in the source code
5. Add a comment at the top of .env.example explaining how to create the real .env fileThis prompt gets your AI tool to do the right thing from the start. The .env.example file is a bonus โ it's a template that shows other developers (or future you) which variables they need to set up, without containing actual secrets.
Immediately go to every service whose key was exposed and rotate (regenerate) the key. Then add .env to your .gitignore and remove the file from tracking with git rm --cached .env (ask your AI tool to walk you through this). Simply deleting the file in a new commit doesn't erase it from Git history โ the secret is still visible to anyone who looks at older commits.
Platforms like Replit and Lovable have built-in secret managers that serve the same purpose. Use those instead โ they encrypt your secrets and keep them out of your code files entirely. You only need an actual .env file when building locally (on your own computer) with tools like Cursor or VS Code.
.env is your actual secrets file that should never be shared. .env.local is the same concept but sometimes used by frameworks like Next.js for local overrides. .env.example is a template โ it contains the variable names with fake placeholder values so someone else (or future you) knows which keys the project needs. Only .env.example should ever be committed to Git.
If you set up environment variables correctly (server-side only), visitors to your website cannot see them. However, if your code sends API keys to the browser โ for example, by using them in client-side JavaScript โ then yes, anyone can find them using browser developer tools. Always use API keys on the server side only. When in doubt, ask your AI tool: "Is this API key being exposed to the browser?"
At minimum, rotate keys whenever someone leaves your project, whenever you suspect any exposure, and every 90 days as a general hygiene practice. Most services (OpenAI, Stripe, AWS) make it easy to generate a new key and deactivate the old one from their dashboard.
.gitignore file must include .env โ without this, your secrets get uploaded.env.example template with placeholder values committed to Gitprocess.env instead of hardcoding secretsBefore tomorrow's lesson, I want you to do one thing: audit one project. Pick the project you're most actively working on. Search for any hardcoded keys. Move them to a .env file or your platform's secret manager. Add .env to your .gitignore. If you find a key that's already been pushed to GitHub, rotate it today.
This takes 10 minutes and it could save you thousands of dollars and weeks of headaches.
You've got this. See you tomorrow.
Share this with someone building with AI tools who might not know about .env files yet. It could save them a very bad day.
Discover more content: