dotenv-patterns
Provides guidelines for managing environment files and credential loading in backend applications, ensuring security and best practices.
Install this skill
Security score
The dotenv-patterns skill was audited on Feb 9, 2026 and we found 126 security issues across 3 threat categories. Review the findings below before installing.
Categories Tested
Security Issues
Template literal with variable interpolation in command context
| 409 | ```yaml |
Template literal with variable interpolation in command context
| 640 | config({ path: `.env.${environment}` }); |
System command execution
| 610 | Set environment variables in your CI system (GitHub Actions secrets, etc.): |
Path traversal pattern
| 300 | import { newService } from '../../src'; |
Path traversal pattern
| 301 | import type { ServiceConnector } from '../../src'; |
Access to .env file
| 3 | description: Environment file (.env) patterns, test data, and credential loading |
Access to .env file
| 6 | # Environment File Patterns (.env) |
Access to .env file
| 10 | ### Rule #1: NEVER Commit .env Files |
Access to .env file
| 12 | - .env files contain secrets |
Access to .env file
| 14 | - Use .env.example as template |
Access to .env file
| 15 | - Each developer has their own .env |
Access to .env file
| 19 | .env |
Access to .env file
| 20 | .env.local |
Access to .env file
| 21 | .env.*.local |
Access to .env file
| 24 | ### Rule #2: ONLY test/integration/Common.ts Reads .env |
Access to .env file
| 26 | - **FORBIDDEN**: `process.env` in `src/` directory (production code) |
Access to .env file
| 29 | - Test files import from Common.ts, NEVER access process.env directly |
Access to .env file
| 35 | config(); // Load .env explicitly |
Access to .env file
| 37 | export const SERVICE_API_KEY = process.env.SERVICE_API_KEY || ''; |
Access to .env file
| 38 | export const SERVICE_BASE_URL = process.env.SERVICE_BASE_URL || 'https://api.example.com'; |
Access to .env file
| 44 | const apiKey = process.env.API_KEY; // NEVER! |
Access to .env file
| 47 | const apiKey = process.env.SERVICE_API_KEY; // Use Common.ts instead! |
Access to .env file
| 50 | // test/unit/Common.ts should NEVER use process.env |
Access to .env file
| 53 | ### Rule #3: ALL Test Values Must Be in .env |
Access to .env file
| 58 | # ✅ CORRECT - Test values in .env |
Access to .env file
| 70 | 1. User gives you test values → Add to `.env` immediately |
Access to .env file
| 75 | ## .env File Structure |
Access to .env file
| 79 | **Create .env in module root** (same directory as package.json): |
Access to .env file
| 83 | ├── .env ← HERE (module root) |
Access to .env file
| 130 | export const SERVICE_API_TOKEN = process.env.SERVICE_API_TOKEN || ''; |
Access to .env file
| 131 | export const SERVICE_BASE_URL = process.env.SERVICE_BASE_URL || 'https://api.example.com'; |
Access to .env file
| 156 | export const SERVICE_CLIENT_ID = process.env.SERVICE_CLIENT_ID || ''; |
Access to .env file
| 157 | export const SERVICE_CLIENT_SECRET = process.env.SERVICE_CLIENT_SECRET || ''; |
Access to .env file
| 158 | export const SERVICE_BASE_URL = process.env.SERVICE_BASE_URL || 'https://api.example.com'; |
Access to .env file
| 159 | export const SERVICE_TOKEN_URL = process.env.SERVICE_TOKEN_URL || 'https://api.example.com/oauth/token'; |
Access to .env file
| 183 | export const SERVICE_EMAIL = process.env.SERVICE_EMAIL || ''; |
Access to .env file
| 184 | export const SERVICE_PASSWORD = process.env.SERVICE_PASSWORD || ''; |
Access to .env file
| 185 | export const SERVICE_BASE_URL = process.env.SERVICE_BASE_URL || 'https://api.example.com'; |
Access to .env file
| 220 | export const SERVICE_API_TOKEN = process.env.SERVICE_API_TOKEN || ''; |
Access to .env file
| 223 | export const SERVICE_EMAIL = process.env.SERVICE_EMAIL || ''; |
Access to .env file
| 224 | export const SERVICE_PASSWORD = process.env.SERVICE_PASSWORD || ''; |
Access to .env file
| 226 | export const SERVICE_BASE_URL = process.env.SERVICE_BASE_URL || 'https://api.example.com'; |
Access to .env file
| 239 | **🚨 CRITICAL: All integration test IDs/values MUST be in .env** |
Access to .env file
| 265 | export const SERVICE_API_KEY = process.env.SERVICE_API_KEY || ''; |
Access to .env file
| 266 | export const SERVICE_BASE_URL = process.env.SERVICE_BASE_URL || 'https://api.example.com'; |
Access to .env file
| 269 | export const SERVICE_TEST_USER_ID = process.env.SERVICE_TEST_USER_ID || ''; |
Access to .env file
| 270 | export const SERVICE_TEST_ORGANIZATION_ID = process.env.SERVICE_TEST_ORGANIZATION_ID || ''; |
Access to .env file
| 271 | export const SERVICE_TEST_RESOURCE_NAME = process.env.SERVICE_TEST_RESOURCE_NAME || ''; |
Access to .env file
| 283 | const userId = SERVICE_TEST_USER_ID; // ✅ From .env |
Access to .env file
| 296 | // test/integration/Common.ts - ONLY file allowed to access process.env |
Access to .env file
| 303 | // Load .env file explicitly to ensure credentials are available |
Access to .env file
| 307 | export const SERVICE_API_KEY = process.env.SERVICE_API_KEY || ''; |
Access to .env file
| 308 | export const SERVICE_EMAIL = process.env.SERVICE_EMAIL || ''; |
Access to .env file
| 309 | export const SERVICE_PASSWORD = process.env.SERVICE_PASSWORD || ''; |
Access to .env file
| 310 | export const SERVICE_BASE_URL = process.env.SERVICE_BASE_URL || 'https://api.example.com'; |
Access to .env file
| 312 | // Test Data Values - export any test IDs, names, or other values from .env |
Access to .env file
| 313 | export const SERVICE_TEST_USER_ID = process.env.SERVICE_TEST_USER_ID || ''; |
Access to .env file
| 314 | export const SERVICE_TEST_ORGANIZATION_ID = process.env.SERVICE_TEST_ORGANIZATION_ID || ''; |
Access to .env file
| 324 | if (process.env.LOG_LEVEL) { |
Access to .env file
| 325 | switch (process.env.LOG_LEVEL) { |
Access to .env file
| 371 | * Uses real credentials from .env file. |
Access to .env file
| 393 | - Explicit `config()` ensures .env is loaded BEFORE env vars are accessed |
Access to .env file
| 398 | ### Local Development (.env file) |
Access to .env file
| 401 | # .env - Local developer credentials |
Access to .env file
| 418 | - Local: .env file for developers |
Access to .env file
| 423 | ## .env.example Template |
Access to .env file
| 425 | **ALWAYS provide .env.example for documentation:** |
Access to .env file
| 428 | # .env.example - Template for setting up credentials |
Access to .env file
| 446 | cp .env.example .env |
Access to .env file
| 447 | vim .env # Add your credentials |
Access to .env file
| 472 | // Load .env file explicitly |
Access to .env file
| 475 | export const SERVICE_API_KEY = process.env.SERVICE_API_KEY || ''; |
Access to .env file
| 491 | // Test with real credentials from .env |
Access to .env file
| 498 | ### Check .env Configuration |
Access to .env file
| 501 | # Verify .env exists |
Access to .env file
| 502 | [ -f .env ] && echo "✅ .env exists" || echo "❌ Missing .env - create it!" |
Access to .env file
| 504 | # Check .env is in .gitignore |
Access to .env file
| 505 | grep -q "^\.env$" .gitignore && echo "✅ .env in .gitignore" || echo "❌ Add .env to .gitignore!" |
Access to .env file
| 508 | grep -q "SERVICE_API_KEY" .env && echo "✅ SERVICE_API_KEY present" || echo "❌ Missing SERVICE_API_KEY" |
Access to .env file
| 520 | grep -E "export const.*=.*process\.env\." test/integration/Common.ts && echo "✅ Exports env vars" || echo "❌ No env var exports" |
Access to .env file
| 526 | ### Check NO process.env in src/ (Security Rule #2) |
Access to .env file
| 530 | grep -r "process\.env" src/ && echo "❌ Found process.env in src/! FORBIDDEN!" || echo "✅ No process.env in src/" |
Access to .env file
| 533 | grep "process\.env" test/unit/Common.ts 2>/dev/null && echo "❌ Found process.env in unit test Common.ts! FORBIDDEN!" || echo "✅ No process.env in unit tests" |
Access to .env file
| 542 | echo " ALL test values must be in .env and imported from Common.ts" |
Access to .env file
| 563 | - [ ] .env is in .gitignore |
Access to .env file
| 564 | - [ ] No .env files committed to git |
Access to .env file
| 565 | - [ ] .env.example created (no real credentials) |
Access to .env file
| 566 | - [ ] No process.env in src/ directory |
Access to .env file
| 567 | - [ ] ONLY test/integration/Common.ts reads process.env |
Access to .env file
| 570 | - [ ] All test values in .env (no hardcoded IDs in tests) |
Access to .env file
| 581 | Create a `.env` file in the module root: |
Access to .env file
| 585 | cp .env.example .env |
Access to .env file
| 622 | # .env.development |
Access to .env file
| 626 | # .env.staging |
Access to .env file
| 630 | # .env.production (NEVER commit!) |
Access to .env file
| 639 | const environment = process.env.NODE_ENV || 'development'; |
Access to .env file
| 640 | config({ path: `.env.${environment}` }); |
Access to .env file
| 646 | # .env |
Access to .env file
| 661 | - ✅ .env file created in module root |
Access to .env file
| 662 | - ✅ .env is in .gitignore |
Access to .env file
| 663 | - ✅ .env.example template provided |
Access to .env file
| 665 | - ✅ test/integration/Common.ts is ONLY file accessing process.env |
Access to .env file
| 668 | - ✅ All test data values in .env (no hardcoded test IDs) |
Access to .env file
| 671 | - ✅ No process.env in src/ directory (CRITICAL) |
Access to .env file
| 672 | - ✅ No process.env in test/unit/Common.ts (unit tests don't use env vars) |
External URL reference
| 38 | export const SERVICE_BASE_URL = process.env.SERVICE_BASE_URL || 'https://api.example.com'; |
External URL reference
| 97 | GITHUB_BASE_URL=https://api.github.com |
External URL reference
| 119 | SERVICE_BASE_URL=https://api.example.com |
External URL reference
| 131 | export const SERVICE_BASE_URL = process.env.SERVICE_BASE_URL || 'https://api.example.com'; |
External URL reference
| 144 | SERVICE_BASE_URL=https://api.example.com |
External URL reference
| 145 | SERVICE_TOKEN_URL=https://api.example.com/oauth/token |
External URL reference
| 158 | export const SERVICE_BASE_URL = process.env.SERVICE_BASE_URL || 'https://api.example.com'; |
External URL reference
| 159 | export const SERVICE_TOKEN_URL = process.env.SERVICE_TOKEN_URL || 'https://api.example.com/oauth/token'; |
External URL reference
| 172 | SERVICE_BASE_URL=https://api.example.com |
External URL reference
| 185 | export const SERVICE_BASE_URL = process.env.SERVICE_BASE_URL || 'https://api.example.com'; |
External URL reference
| 198 | SERVICE_BASE_URL=https://api.example.com |
External URL reference
| 210 | SERVICE_BASE_URL=https://api.example.com |
External URL reference
| 226 | export const SERVICE_BASE_URL = process.env.SERVICE_BASE_URL || 'https://api.example.com'; |
External URL reference
| 244 | SERVICE_BASE_URL=https://api.example.com |
External URL reference
| 266 | export const SERVICE_BASE_URL = process.env.SERVICE_BASE_URL || 'https://api.example.com'; |
External URL reference
| 310 | export const SERVICE_BASE_URL = process.env.SERVICE_BASE_URL || 'https://api.example.com'; |
External URL reference
| 432 | SERVICE_BASE_URL=https://api.example.com |
External URL reference
| 589 | SERVICE_BASE_URL=https://api.example.com |
External URL reference
| 623 | SERVICE_BASE_URL=https://dev-api.example.com |
External URL reference
| 627 | SERVICE_BASE_URL=https://staging-api.example.com |
External URL reference
| 631 | SERVICE_BASE_URL=https://api.example.com |