Phase 6: Building With Real Data · 20 min · Any vibe coding tool · Vercel · Netlify
Objective
Your mission
Find all hardcoded secrets in your project, move them to .env, and verify .gitignore is correct. Output: secrets_audit.md.
You need: A project with API keys, database credentials, or any secrets.
Time: 20 minutes.
Step 1: learn the pattern (3 min)
BAD — hardcoded:
const supabase = createClient('https://xxxxx.supabase.co', 'eyJhbGciOi...')
If pushed to GitHub, anyone can see your keys. Bots scan repos within minutes.
GOOD — environment variables:
const supabase = createClient(
import.meta.env.VITE_SUPABASE_URL,
import.meta.env.VITE_SUPABASE_ANON_KEY
)
Naming: Vite apps use VITE_ prefix. Next.js uses NEXT_PUBLIC_. Check your framework's docs.
Safe vs. dangerous keys: | Key | Safe in Frontend? | Why | |-----|-------------------|-----| | Supabase anon key | Yes | Restricted by RLS | | Supabase service_role | NO | Bypasses all security | | Stripe publishable key | Yes | Client-side only | | Stripe secret key | NO | Full account access | | OpenAI API key | NO | Full account + billing |
Rule of thumb: "publishable," "public," or "anon" = usually safe. "secret," "service," or "private" = server only.
The .env commit mistake
The most common secret leak in vibe-coded apps: the AI creates .env but doesn't add it to .gitignore. The user pushes to GitHub. Secrets are now public. ALWAYS check that .env is in .gitignore before pushing. If you've already pushed, rotate the keys immediately.
Step 2: search for hardcoded secrets (5 min)
Search your codebase for common secret patterns:
# Search for API key patterns
grep -r "sk_" src/
grep -r "eyJ" src/
grep -r "password" src/
grep -r "secret" src/
grep -r "key=" src/
grep -r "supabase.co" src/
Write in your file:
## Secrets Found
1. File: [path] — Line: [number] — Secret type: [e.g., Supabase URL, API key]
2. [repeat for each]
[or write "No hardcoded secrets found"]
Step 3: move secrets to .env (5 min)
Create a .env file in your project root:
VITE_SUPABASE_URL=https://xxxxx.supabase.co
VITE_SUPABASE_ANON_KEY=eyJhbGciOi...
Create a .env.example (safe to commit — placeholders only):
VITE_SUPABASE_URL=your-supabase-url-here
VITE_SUPABASE_ANON_KEY=your-anon-key-here
Update your code to reference environment variables instead of hardcoded values.
Write in your file:
## .env Created
Variables added: [list]
.env.example created with placeholders: [yes/no]
Code updated to use import.meta.env.VITE_*: [yes/no]
Step 4: verify .gitignore (3 min)
Check that .env is in your .gitignore:
cat .gitignore | grep .env
If it's not there, add it:
.env
.env.local
.env.*.local
If .env was already committed:
- Remove from tracking:
git rm --cached .env - Add to
.gitignore - Rotate (regenerate) any committed keys — they're compromised
Write in your file:
## .gitignore Check
.env in .gitignore: [yes/no]
If was committed, removed from tracking: [yes/no/N/A]
Keys rotated (if compromised): [yes/no/N/A]
Step 5: verify the app still works (2 min)
Run your app and make sure it still connects to Supabase (or whatever service) using the environment variables.
Write in your file:
## Verification
App works with env vars: [yes/no]
No secrets remaining in code: [yes/no — verified with grep]
Step 6: if deploying — set env vars on platform (2 min)
- Vercel: Project Settings → Environment Variables → add each → redeploy
- Netlify: Site Settings → Environment Variables → add each → redeploy
Write in your file:
## Deployment Env Vars
Platform: [Vercel/Netlify/other/N/A]
All env vars set on platform: [yes/no/N/A]
You moved your keys into .env, then pushed to GitHub. What must you check first?
The most common leak: .env exists but isn't ignored, so it gets pushed. If it was pushed, rotate the keys immediately.