Environment Variables and Security
Environment Variables and Security
Protect Your Secrets · .env · process.env
By AI Learning Assistant · Node.js Security · Environment Variables · Best Practices
🤖 AI-POWERED LESSON
This article is paired with a live AI session. You will learn to protect your API keys and sensitive data using environment variables — a critical skill for any production application. Every code block includes detailed line-by-line comments.
Every day, thousands of developers accidentally expose their API keys on GitHub. Bots scan repositories constantly, looking for keys. Within minutes of a public commit, those keys are compromised and used by attackers. The cost can range from a few dollars in API charges to complete account takeover.
The solution is simple but crucial: environment variables. Instead of hardcoding secrets in your source code, you store them in a special file (`.env`) that never gets committed to version control. Your code reads these values at runtime from the environment. This keeps secrets out of your codebase while still making them available to your application.
We will cover what environment variables are, using dotenv to load .env files, accessing variables with process.env, creating .gitignore to protect secrets, and the top 5 security mistakes beginners make with API keys. By the end, you will know how to keep your secrets safe.
What Are Environment Variables?
KEY-VALUE PAIRS · SEPARATE FROM CODE
Environment variables are key-value pairs stored outside your application code. They are set in the operating system's environment and accessed by your application at runtime. In Node.js, you access them through the process.env object.
The dotenv package loads variables from a `.env` file into process.env automatically. This allows you to have different configurations for development, staging, and production without changing your code.
📜 CODE BLOCK 1: Complete Environment Setup (with line-by-line comments)
// ============================================ // STEP 1: INSTALL DOTENV // ============================================ // $ npm install dotenv // ============================================ // STEP 2: CREATE .env FILE // ============================================ // Create a file named .env in your project root with content: // // OPENAI_API_KEY=sk-abc123yourkeyhere // PORT=3000 // APP_NAME=Webbo3 // DATABASE_URL=postgresql://localhost:5432/mydb // NODE_ENV=development // ============================================ // STEP 3: CREATE .gitignore FILE // ============================================ // Create .gitignore in your project root with content: // // .env // node_modules/ // .env.local // .env.production // *.log // .DS_Store // ============================================ // STEP 4: LOAD AND USE ENVIRONMENT VARIABLES // ============================================ // WHY: Load environment variables from .env file into process.env // HOW: This must be called BEFORE using any environment variables require("dotenv").config(); // WHY: Import the OpenAI SDK const OpenAI = require("openai"); // WHY: Initialize client using API key from environment variable // Notice: No hardcoded key! The key stays in .env, not in source code const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); // WHY: Read other configuration values from environment // This makes the app configurable without code changes const PORT = process.env.PORT || 3000; // Fallback default if not set const APP_NAME = process.env.APP_NAME || "MyApp"; const NODE_ENV = process.env.NODE_ENV || "development"; // WHY: Check if API key is available (but don't log the actual key!) // !! converts any truthy value to true, falsy to false console.log("App:", APP_NAME); console.log("Port:", PORT); console.log("Environment:", NODE_ENV); console.log("AI is ready:", !!process.env.OPENAI_API_KEY); // ============================================ // SECURITY CHECK: Add this to validate required vars // ============================================ if (!process.env.OPENAI_API_KEY) { console.error("FATAL ERROR: OPENAI_API_KEY is not set in environment variables"); console.error("Create a .env file with OPENAI_API_KEY=your_key_here"); process.exit(1); // Exit with error code, don't start the app }
Why Hardcoding is Dangerous
SECURITY BREACH · ACCOUNT TAKEOVER · FINANCIAL LOSS
🚫 THE DANGER OF HARDCODED SECRETS
What happens when you hardcode an API key? The key becomes part of your source code. If you commit that code to GitHub (public or private), anyone with access can see it. But worse — automated bots constantly scan GitHub commits for patterns that look like API keys. When they find one, they immediately start using it.
Real consequences: Attackers can make API calls on your account (costing you money), access your users' data, delete your resources, or use your infrastructure for their own purposes. Some developers have received bills for $50,000+ from compromised cloud accounts.
The fix is simple: Use environment variables and never commit your .env file.
Essential .gitignore Reference
WHAT TO EXCLUDE FROM VERSION CONTROL
# ============================================ # RECOMMENDED .gitignore FOR NODE.JS PROJECTS # ============================================ # Environment variables (CRITICAL — contains secrets!) .env .env.local .env.production .env.staging .env.*.local # Dependencies (can be regenerated with npm install) node_modules/ # Logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* # OS generated files .DS_Store .DS_Store? ._* .Spotlight-V100 .Trashes ehthumbs.db Thumbs.db # Editor files .vscode/ .idea/ *.swp *.swo *~ # Build outputs dist/ build/ out/ # Coverage directories coverage/ .nyc_output/
Production Environment Variables
PLATFORM-SPECIFIC · NEVER COMMIT
In production, you don't use a .env file. Instead, each hosting platform provides a way to set environment variables through their dashboard or CLI:
🌐 Platform-Specific Methods:
- Heroku: heroku config:set OPENAI_API_KEY=value
- Vercel: vercel env add OPENAI_API_KEY or Dashboard → Settings → Environment Variables
- Netlify: Site settings → Build & deploy → Environment → Environment variables
- AWS Elastic Beanstalk: Environment properties in configuration
- DigitalOcean App Platform: App spec with env variables or Dashboard → Settings → Environment Variables
- Render: Dashboard → Environment → Environment Variables
The .env file is for local development only. In production, set variables through your platform's secure interface.
📜 CODE BLOCK 3: Environment Variable Validation Pattern
// ============================================ // PROFESSIONAL VALIDATION PATTERN // ============================================ // Load dotenv first require("dotenv").config(); // Define required environment variables const requiredEnvVars = [ "OPENAI_API_KEY", "DATABASE_URL" ]; // Check each required variable const missingVars = requiredEnvVars.filter(varName => !process.env[varName]); // If any are missing, exit with clear error message if (missingVars.length > 0) { console.error("❌ Missing required environment variables:"); missingVars.forEach(v => console.error(` - ${v}`)); console.error("\n💡 Create a .env file with these variables or set them in your environment."); process.exit(1); } // Helper to get environment variable with type conversion function env(key, defaultValue = null) { const value = process.env[key]; if (value === undefined && defaultValue === null) { throw new Error(`Environment variable ${key} is required but not set`); } return value !== undefined ? value : defaultValue; } // Usage: const PORT = env("PORT", "3000"); const API_KEY = env("OPENAI_API_KEY"); // Will throw error if missing
Quick Comparison
| Practice | ❌ Insecure | ✅ Secure |
|---|---|---|
| API Key Storage | Hardcoded in source code | process.env with .env file |
| Version Control | .env committed to git | .env in .gitignore |
| Debugging | Logging full secrets | Logging presence only (!!key) |
| Environment Separation | Same key for dev/prod | Different keys with least privilege |
| Frontend Keys | API keys in client-side JS | Backend-only proxy pattern |
🤖 HOW AI ACCELERATES THIS TOPIC
Ask AI: "Scan this code snippet and tell me if there are any hardcoded secrets or security issues." Get an instant security audit.
Ask: "I accidentally committed my .env file with real API keys. What do I do now?" Get step-by-step incident response steps.
Ask: "Generate a .gitignore file for a Node.js project with all security-sensitive files excluded." Get production-ready configuration.
AI-Assisted JavaScript Learning · Environment Variables · Keep Your Secrets Safe
Complete this lesson
Mark as complete to track your progress