[{"data":1,"prerenderedAt":308},["ShallowReactive",2],{"blog-how-to/secure-api-keys":3},{"id":4,"title":5,"body":6,"category":289,"date":290,"dateModified":290,"description":291,"draft":292,"extension":293,"faq":294,"featured":292,"headerVariant":295,"image":294,"keywords":294,"meta":296,"navigation":297,"ogDescription":298,"ogTitle":294,"path":299,"readTime":294,"schemaOrg":300,"schemaType":301,"seo":302,"sitemap":303,"stem":304,"tags":305,"twitterCard":306,"__hash__":307},"blog/blog/how-to/secure-api-keys.md","How to Secure API Keys in Your Web App",{"type":7,"value":8,"toc":276},"minimark",[9,13,17,21,30,35,38,42,69,89,109,129,148],[10,11],"category-badge",{"category":12},"How-To Guide",[14,15,5],"h1",{"id":16},"how-to-secure-api-keys-in-your-web-app",[18,19,20],"p",{},"Step-by-step guide for vibe coders",[22,23,24,27],"tldr",{},[18,25,26],{},"TL;DR",[18,28,29],{},"Never put API keys in your code. Use environment variables (.env files) and keep them out of git. Secret keys (like Stripe's sk_) should only be used server-side. If a key is leaked, rotate it immediately.",[31,32,34],"h2",{"id":33},"why-this-matters","Why This Matters",[18,36,37],{},"Exposed API keys are the #1 security issue in vibe-coded apps. When AI generates code, it often uses placeholder keys or puts real keys directly in the code. These can end up in your git history, exposing them to anyone who can see your repository.",[31,39,41],{"id":40},"step-by-step-guide","Step-by-Step Guide",[43,44,46,51,59],"step",{"number":45},"1",[47,48,50],"h3",{"id":49},"create-a-env-file","Create a .env file",[18,52,53,54,58],{},"Create a file named ",[55,56,57],"code",{},".env.local"," in your project root:",[60,61,66],"pre",{"className":62,"code":64,"language":65},[63],"language-text","# .env.local\nDATABASE_URL=postgresql://user:password@localhost:5432/mydb\nSTRIPE_SECRET_KEY=sk_test_xxxxx\nOPENAI_API_KEY=sk-xxxxx\n\n# Safe for client (public keys only)\nNEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co\nNEXT_PUBLIC_SUPABASE_ANON_KEY=eyJxxxx\n","text",[55,67,64],{"__ignoreMap":68},"",[43,70,72,76,83],{"number":71},"2",[47,73,75],{"id":74},"add-env-files-to-gitignore","Add .env files to .gitignore",[18,77,78,79,82],{},"Open (or create) ",[55,80,81],{},".gitignore"," and add:",[60,84,87],{"className":85,"code":86,"language":65},[63],"# Environment files\n.env\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n.env.production\n\n# Keep the example file\n!.env.example\n",[55,88,86],{"__ignoreMap":68},[43,90,92,96,103],{"number":91},"3",[47,93,95],{"id":94},"create-an-example-file","Create an example file",[18,97,98,99,102],{},"Create ",[55,100,101],{},".env.example"," with placeholder values for documentation:",[60,104,107],{"className":105,"code":106,"language":65},[63],"# .env.example (commit this file)\nDATABASE_URL=postgresql://user:password@localhost:5432/mydb\nSTRIPE_SECRET_KEY=sk_test_your_key_here\nOPENAI_API_KEY=sk-your_key_here\n\nNEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co\nNEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key_here\n",[55,108,106],{"__ignoreMap":68},[43,110,112,116,123],{"number":111},"4",[47,113,115],{"id":114},"use-environment-variables-in-code","Use environment variables in code",[18,117,118,119,122],{},"Access keys using ",[55,120,121],{},"process.env",":",[60,124,127],{"className":125,"code":126,"language":65},[63],"// Server-side code\nconst stripe = new Stripe(process.env.STRIPE_SECRET_KEY);\n\n// Verify key exists\nif (!process.env.STRIPE_SECRET_KEY) {\n  throw new Error('Missing STRIPE_SECRET_KEY');\n}\n",[55,128,126],{"__ignoreMap":68},[43,130,132,136,142],{"number":131},"5",[47,133,135],{"id":134},"keep-secret-keys-server-side-only","Keep secret keys server-side only",[18,137,138,139,122],{},"In Next.js, don't prefix secret keys with ",[55,140,141],{},"NEXT_PUBLIC_",[60,143,146],{"className":144,"code":145,"language":65},[63],"# WRONG - This exposes the key to the browser\nNEXT_PUBLIC_STRIPE_SECRET=sk_live_xxxxx\n\n# CORRECT - This stays server-side only\nSTRIPE_SECRET_KEY=sk_live_xxxxx\n",[55,147,145],{"__ignoreMap":68},[43,149,151,155,158,187,266,271],{"number":150},"6",[47,152,154],{"id":153},"set-production-variables-in-your-hosting-platform","Set production variables in your hosting platform",[18,156,157],{},"Don't deploy .env files. Instead, set variables in your hosting dashboard:",[159,160,161,169,175,181],"ul",{},[162,163,164,168],"li",{},[165,166,167],"strong",{},"Vercel:"," Project Settings > Environment Variables",[162,170,171,174],{},[165,172,173],{},"Railway:"," Project > Variables",[162,176,177,180],{},[165,178,179],{},"Netlify:"," Site Settings > Environment Variables",[162,182,183,186],{},[165,184,185],{},"Render:"," Service > Environment\n::",[188,189,190,193,196,211,215,237,241,247,257],"warning-box",{},[18,191,192],{},"If Your Key Was Exposed",[18,194,195],{},"If you accidentally committed a key to git:",[197,198,199,202,205,208],"ol",{},[162,200,201],{},"Immediately rotate the key in the service's dashboard",[162,203,204],{},"Update your production environment with the new key",[162,206,207],{},"Don't try to remove it from git history - consider it compromised",[162,209,210],{},"Check logs for unauthorized usage\n::",[31,212,214],{"id":213},"common-mistakes-to-avoid","Common Mistakes to Avoid",[159,216,217,220,228,231,234],{},[162,218,219],{},"Hardcoding keys in source files",[162,221,222,223,227],{},"Using NEXT",[224,225,226],"em",{},"PUBLIC"," prefix for secret keys",[162,229,230],{},"Committing .env files to git",[162,232,233],{},"Sharing production keys across development and production",[162,235,236],{},"Putting keys in frontend code that gets bundled",[31,238,240],{"id":239},"how-to-check-for-exposed-keys","How to Check for Exposed Keys",[60,242,245],{"className":243,"code":244,"language":65},[63],"# Search your codebase for common key patterns\ngrep -r \"sk_live\\|sk_test\\|api_key\\|apiKey\" --include=\"*.ts\" --include=\"*.js\"\n\n# Check if .env files are tracked in git\ngit ls-files | grep -E \"^\\.env\"\n\n# Check git history for keys\ngit log -p | grep -E \"sk_live|sk_test|api_key\"\n",[55,246,244],{"__ignoreMap":68},[18,248,249,252,253,256],{},[165,250,251],{},"Automate this:"," Run ",[55,254,255],{},"npx checkyourvibe scan"," to automatically detect exposed API keys in your codebase.",[258,259,260],"related-articles",{},[261,262],"related-card",{"description":263,"href":264,"title":265},"How Cursor, Bolt, and Lovable handle secrets — and how to stop leaks","/blog/best-practices/ai-api-key-exposure","Why AI Code Generators Expose Your API Keys",[261,267],{"description":268,"href":269,"title":270},"What they are and how to fix them","/blog/vulnerabilities/exposed-api-keys","Exposed API Keys Explained",[261,272],{"description":273,"href":274,"title":275},"Set up automated secret detection in CI","/blog/how-to/secret-scanning","How to Enable Secret Scanning",{"title":68,"searchDepth":277,"depth":277,"links":278},2,[279,280],{"id":33,"depth":277,"text":34},{"id":40,"depth":277,"text":41,"children":281},[282,284,285,286,287,288],{"id":49,"depth":283,"text":50},3,{"id":74,"depth":283,"text":75},{"id":94,"depth":283,"text":95},{"id":114,"depth":283,"text":115},{"id":134,"depth":283,"text":135},{"id":153,"depth":283,"text":154},"how-to","2026-01-22","Step-by-step guide to securing API keys in web applications. Environment variables, server-side handling, key rotation, and what to do if keys are exposed.",false,"md",null,"yellow",{},true,"Step-by-step guide to securing API keys. Environment variables, rotation, and more.","/blog/how-to/secure-api-keys","[object Object]","HowTo",{"title":5,"description":291},{"loc":299},"blog/how-to/secure-api-keys",[],"summary_large_image","7CaTqCoVMIoA_Ii_gjEZfPJxx47dMM5PVjRBgH3-ypM",1775843927853]