TL;DR
Development features in production cause breaches. Debug modes, test credentials, and development APIs should never reach production. Use environment variables, separate databases, and build-time checks to ensure clean separation. These prompts help you audit and fix environment issues.
Environment Audit
Paste this prompt into your AI assistant to get a full audit of your dev/production separation. You'll get a detailed report covering debug modes, test credentials, exposed endpoints, database connections, logging, and source code exposure.
Audit Environment Separation
Audit my application for dev/production separation issues.
Check for:
- Debug modes in production:
- DEBUG=true, NODE_ENV !== 'production'
- Verbose error messages
- Stack traces in responses
- Development middleware (hot reload, etc.)
- Test credentials in production:
- Test API keys
- Default passwords
- Hardcoded tokens
- Development endpoints:
- /debug, /test, /dev routes
- GraphQL introspection enabled
- API documentation exposed
- phpinfo(), /env, /.env accessible
- Database concerns:
- Dev database connected in production
- Test data in production database
- Seed data or admin test accounts
- Logging:
- Verbose logging in production
- Sensitive data in logs
- Log files publicly accessible
- Source exposure:
- Source maps in production
- .git directory accessible
- Environment files exposed
Environment Variables
Use this prompt to set up a complete environment variable system with proper file structure, gitignore rules, and startup validation using zod or envalid.
Configure Environment Variables
Set up proper environment variable handling.
File structure: .env.example # Template with dummy values (committed) .env.local # Local development (gitignored) .env.development # Development defaults (optional) .env.production # Production (set in deployment platform, NOT committed)
.gitignore: .env .env.local .env.production .env*.local
Validation at startup: const requiredEnvVars = 'DATABASE_URL', 'API_KEY', 'JWT_SECRET';
for (const envVar of requiredEnvVars) {
if (!process.envenvVar) {
console.error(Missing required environment variable: ${envVar});
process.exit(1);
}
}
// Validate NODE_ENV const validEnvs = 'development', 'production', 'test'; if (!validEnvs.includes(process.env.NODE_ENV)) { console.error('Invalid NODE_ENV'); process.exit(1); }
Use a library like envalid or zod for typed validation: import { z } from 'zod';
const envSchema = z.object({ NODE_ENV: z.enum('development', 'production', 'test'), DATABASE_URL: z.string().url(), API_KEY: z.string().min(1), });
Never commit .env files with real secrets: Even if you later remove them, they remain in git history. Use git-secrets or similar tools to prevent accidental commits. Rotate any secrets that were ever committed.
Conditional Features
Copy this prompt to generate environment-aware feature toggles for your app. Your AI will create patterns for dev-only middleware, production security hardening, environment-specific error handling, and build-time dead code elimination.
Environment-Specific Features
Implement environment-specific features safely.
Pattern for dev-only features:
const isDev = process.env.NODE_ENV === 'development'; const isProd = process.env.NODE_ENV === 'production';
// Dev-only middleware if (isDev) { app.use(morgan('dev')); app.use('/debug', debugRoutes); }
// Production security if (isProd) { app.use(helmet()); app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));
// Disable features app.disable('x-powered-by'); }
// Error handling differs app.use((err, req, res, next) => { console.error(err);
if (isProd) { res.status(500).json({ error: 'Internal server error' }); } else { res.status(500).json({ error: err.message, stack: err.stack }); } });
// Build-time dead code elimination (webpack/rollup) if (process.env.NODE_ENV !== 'production') { // This code is removed from production build require('./devTools'); }
Never use environment checks for security-critical features - use proper access control.
Separate Databases
This prompt asks your AI to configure complete database isolation across environments. You'll get environment-specific connection strings, safety checks that prevent accidental production connections, and seed/migration safeguards.
Database Environment Separation
Ensure development and production databases are completely separate.
Requirements:
- Separate database instances:
- Development: Local or dev server
- Staging: Copy of production structure, no real data
- Production: Production server with real data
- Environment-specific connection strings:
.env.development
DATABASE_URL=postgresql://localhost:5432/myapp_dev.env.production (set in platform)
DATABASE_URL=postgresql://prod-server:5432/myapp_prod - Prevent accidental production connection:
const dbUrl = process.env.DATABASE_URL;
if (process.env.NODE_ENV === 'development' && dbUrl.includes('prod')) { throw new Error('Refusing to connect to production database in development'); } - Seed data safety: // Only run seeds in development if (process.env.NODE_ENV === 'production') { throw new Error('Cannot run seeds in production'); }
- Migration safety:
- Require confirmation for production migrations
- Use separate migration tracking per environment
- Never run destructive migrations in production without backup
Pro tip: Use different credentials, different cloud accounts, or at minimum different database names for each environment. Make it physically impossible to accidentally connect dev tools to production data.
Should staging use production data?
Ideally no - use anonymized or synthetic data. If you must use production data, ensure it's properly anonymized (PII removed), and staging has the same security controls as production.
How do I test production-like conditions safely?
Use staging environments that mirror production infrastructure but with test data. Load test against staging, not production. Use feature flags to gradually roll out to production users.
Further Reading
Want to understand the vulnerability before fixing it? These guides explain what's happening and why.
Check Your Environment Config
Scan for development features accidentally exposed in production.