Why Did Your OpenAI API Key Suddenly Stop Working?

After learning how to deploy websites with Vercel, you might have enthusiastically built a cool website integrating ChatGPT API and pushed it to GitHub.
Ten minutes later, your phone suddenly receives an alarming email from OpenAI: "🚨 We've detected that your API Key has been leaked to a public GitHub repository. To protect your account security, we've forcibly revoked this key!"

That's when you realize—you hardcoded that priceless sk-proj-xxxxxxxx password directly into your source code (app.js or page.tsx)!

In software engineering, this is called "running naked."
If it's a database password that gets leaked, hackers can log in and wipe your data, then ransom you. If it's an AWS server password, hackers can use your account for crypto mining, leaving you with a six-figure bill the next day!

To avoid such catastrophic scenarios, engineers worldwide invented a mechanism: Environment Variables.


What Are Environment Variables? Complete Isolation of Code and Secrets

The core concept of environment variables is simple: "Write all sensitive credentials in a hidden file called .env. And this file must never be uploaded to GitHub!"

Step 1: Create the .env File

In your project's root directory (usually the same level as package.json), create a file named .env (or .env.local in Next.js).
It should look like this:

OPENAI_API_KEY=sk-proj-your-real-key
DATABASE_PASSWORD=your-strong-password
NEXT_PUBLIC_API_URL=https://api.example.com

Step 2: Access It in Your Code

In your JavaScript/TypeScript code, never hardcode passwords again. Instead, use this incantation to "summon" environment variables:

// Wrong way (will bankrupt you)
// const apiKey = "sk-proj-123456789"; 

// Correct way (access the invisible vault)
const apiKey = process.env.OPENAI_API_KEY;

Now your code becomes an "empty shell"—it only knows to fetch from the vault but has no idea what's inside.

Step 3: Blacklist .env (.gitignore)

This is the most critical step! We must strictly forbid Git from snapshotting the .env file.
Locate the .gitignore file in your project (usually pre-created by frameworks) and ensure it includes:

.env
.env.local

With this line, Git will treat these files as invisible. No matter how many times you click Commit and Push, these secrets will stay safely on your local hard drive—never flying to GitHub!


The Cloud Vault: Vercel's Environment Variables Setup

At this point, you might wonder:
"Wait, if secrets aren't uploaded to GitHub, won't Vercel fail to read them when pulling code for deployment? Won't my live site break?"

This is an extremely smart and critical question!

Yes, Vercel can't access .env. So, you must manually hand over the secrets in Vercel's dashboard—like entrusting your store keys to a reliable manager.

  1. Log in to Vercel dashboard and select your project.
  2. Click Settings at the top.
  3. Find Environment Variables in the left menu.
  4. Fill in the form:
    • Key: Enter OPENAI_API_KEY
    • Value: Paste your real key sk-proj-...
  5. Click Save.

🚨 Vercel's Hidden Pitfall: Redeploy
After adding/modifying environment variables in Vercel, they won't take effect immediately!
Vercel injects secrets only during the "Build" phase.
To trigger this, manually redeploy:
Go to Deployments, find the latest record, click the three dots ..., and select Redeploy.

After ~1 minute of rebuilding, your live site will securely access the API key!


Vibe Prompt in Action: Let AI Audit Your Security Gaps

As a beginner, you might accidentally hardcode secrets without noticing in hundreds of lines.
Before pushing to GitHub, recite this ultimate security spell to your cursor:

【Security Audit Prompt】
I'm about to push this project to public GitHub.
Please scan the entire project (especially files under src/ and app/).

  1. Check for any hardcoded API Keys, Tokens, Passwords, or database connection strings.
  2. If found, refactor them into process.env.XXX environment variables.
  3. Verify .gitignore ensures all .env files are excluded.
  4. List all environment variable names (Keys) I need to manually add in Vercel later.

This prompt is priceless! It's like hiring a senior white-hat hacker for a final pre-launch review. AI will expose all careless vulnerabilities, ensuring your trade secrets remain uncompromised.

In the next chapter, we'll teach you how to ditch the free .vercel.app subdomain and claim your own custom domain—a bold branded URL!

Why Environment Variables Matter

Hardcoded configuration values are a security risk and a maintenance nightmare. Environment variables keep secrets out of your code, make deployments environment-aware, and enable different configs for dev, staging, and production.

Why this matters for your career:

  • Exposed API keys and database passwords cause real security incidents
  • Environment variables are the standard way to manage configuration
  • Understanding env var security is essential for production deployments
  • Misconfigured environment variables are a top cause of deployment failures

Environment Variables in Vercel

Setting Via Dashboard

  1. Go to your Vercel project dashboard
  2. Click Settings → Environment Variables
  3. Add each variable with key and value
  4. Choose which environments: Production, Preview, Development
  5. Save

Setting Via Vercel CLI

# Set a single variable
vercel env add DATABASE_URL
# Prompts for value and environment

# Set for all environments at once
vercel env add PLAUSIBLE_HOST

Setting Via vercel.json

{
  "env": {
    "NEXT_PUBLIC_API_URL": "https://api.myapp.com",
    "NEXT_PUBLIC_GA_ID": "G-XXXXXXXXXX"
  }
}

Note: Variables set in vercel.json are public. Never put secrets here.

Public vs. Secret Variables

| Type | Prefix | Accessible in Browser | Use For | |------|--------|---------------------|---------| | Public | NEXT_PUBLIC_ | Yes | API URLs, feature flags, GA IDs | | Secret | No prefix | No | API keys, DB URLs, auth tokens |

// Public: accessible in browser
const apiUrl = process.env.NEXT_PUBLIC_API_URL;

// Secret: NOT accessible in browser (server-only)
const dbUrl = process.env.DATABASE_URL;

// Trying to use a secret in browser returns undefined

Security Best Practices

| Practice | Why | |----------|-----| | Never hardcode secrets in source code | They will end up in version control | | Use .env.local for local development | Git-ignored by default | | Use .env.example as a template | Document required variables without exposing values | | Rotate secrets regularly | If a key is leaked, limit the damage window | | Use different keys per environment | Dev, staging, and production should have separate keys | | Restrict Vercel team access | Only team members who need secrets should see them | | Audit environment variables regularly | Remove unused or expired keys | | Use Vercel's encrypted storage | Secrets are encrypted at rest | | Never log environment variables | Accidental exposure in build logs | | Use short-lived tokens when possible | Reduces risk if tokens are exposed |

.env File Management

# .env.local (local development, git-ignored)
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
OPENAI_API_KEY=sk-...

# .env.example (committed to git, shows required vars without values)
DATABASE_URL=
OPENAI_API_KEY=
NEXT_PUBLIC_API_URL=

# .env.production (for local production testing)
DATABASE_URL=postgresql://user:pass@prod-host:5432/mydb
NEXT_PUBLIC_API_URL=https://api.myapp.com

Common Environment Variables

| Variable | Purpose | Example | |----------|---------|--------| | DATABASE_URL | Database connection string | postgresql://user:pass@host:5432/db | | NEXT_PUBLIC_API_URL | Public API base URL | https://api.myapp.com | | NEXT_PUBLIC_GA_ID | Google Analytics ID | G-XXXXXXXXXX | | OPENAI_API_KEY | OpenAI API key | sk-... | | SUPABASE_URL | Supabase project URL | https://abc123.supabase.co | | SUPABASE_ANON_KEY | Supabase anonymous key | eyJhbGciOiJIUzI1NiIs... | | STRIPE_SECRET_KEY | Stripe secret key | sk_live_... | | STRIPE_WEBHOOK_SECRET | Stripe webhook signing secret | whsec_... | | SENDGRID_API_KEY | Email service API key | SG.xxxxx | | NODE_ENV | Environment identifier | production, development, test |

Summary

Environment variables keep secrets secure and configuration flexible. Use NEXT_PUBLIC_ prefix for client-accessible variables, keep all secrets server-only, use .env.local for local development, and set variables per environment in Vercel.

Key takeaways:

  • Never hardcode secrets in source code
  • Use NEXT_PUBLIC_ prefix for browser-accessible public variables
  • All other variables are server-only
  • Set variables per environment (Production, Preview, Development)
  • Use .env.local for local dev (git-ignored)
  • Use .env.example for documenting required variables
  • Rotate secrets regularly
  • Audit and remove unused variables
  • Logging environment variables can leak secrets

What's Next: Custom Domain

The next chapter covers configuring a custom domain for your Vercel deployment — DNS setup, SSL certificates, domain verification, and production URLs.

Unlock Full Tutorial

This chapter is paid content. Join the project to unlock over 5000 words of deep analysis, including 10+ god-tier Prompts and real Source Code examples!