Environment Setup Guide

Setting Up a Secure Environment for Your Vibe Coding Project

Seven steps to secure your development environment before writing a single prompt.

Sherlock Forensics provides a free step-by-step guide for securing vibe coding environments. Covers version control with .gitignore templates, environment variable management, dependency security, security headers, HTTPS setup with Let's Encrypt, database hardening and a pre-deployment checklist. Includes copyable configuration snippets for Node.js, Python and PHP. Professional audits from $1,500 CAD. Contact 604.229.1994.

Seven Steps

Secure Your Environment

Step 1 of 7

Version Control Security

Your .gitignore file is your first line of defense against accidentally committing secrets. AI coding tools generate .env files, config files and API keys that must never reach your repository.

.gitignore Template

# Environment and secrets
.env
.env.local
.env.production
.env.*.local

# Dependencies
node_modules/
vendor/
__pycache__/
*.pyc
venv/
.venv/

# Build output
dist/
build/
.next/
out/

# IDE and OS
.vscode/
.idea/
.DS_Store
Thumbs.db

# Logs and databases
*.log
*.sqlite
*.sqlite3
*.db

# Certificates and keys
*.pem
*.key
*.cert
*.crt

Pre-commit Hook for Secret Detection

Save this as .git/hooks/pre-commit and make it executable with chmod +x .git/hooks/pre-commit.

#!/bin/bash
# Pre-commit hook: block commits containing secrets
PATTERNS="AKIA[0-9A-Z]{16}|sk_live_|sk_test_|password\s*=\s*['\"][^'\"]+['\"]|API_KEY\s*=\s*['\"][^'\"]+['\"]"

if git diff --cached --diff-filter=ACM | grep -qEi "$PATTERNS"; then
  echo "ERROR: Potential secret detected in staged files."
  echo "Review your changes and remove any API keys or passwords."
  exit 1
fi
exit 0
Common AI coding mistake: AI tools frequently create .env files and then import them directly in client-side code, exposing secrets to every browser. They also rarely suggest adding a .gitignore file, meaning your first commit may include your entire .env file in the repository history.

Step 2 of 7

Environment Variables

Never hardcode API keys, database passwords or secret tokens in your source code. Use a .env file locally and environment variables in production.

.env Template

# Application
NODE_ENV=development
PORT=3000
APP_URL=http://localhost:3000

# Database
DATABASE_URL=postgresql://user:password@localhost:5432/myapp
DB_SSL=false

# Authentication
JWT_SECRET=CHANGE_ME_TO_RANDOM_64_CHAR_STRING
SESSION_SECRET=CHANGE_ME_TO_ANOTHER_RANDOM_STRING

# Third-party APIs
STRIPE_SECRET_KEY=sk_test_...
STRIPE_PUBLISHABLE_KEY=pk_test_...
OPENAI_API_KEY=sk-...

# Email
SMTP_HOST=smtp.example.com
SMTP_USER=noreply@example.com
SMTP_PASS=CHANGE_ME

Loading Environment Variables

Node.js

// Install: npm install dotenv
require('dotenv').config();

// Access variables
const dbUrl = process.env.DATABASE_URL;
const jwtSecret = process.env.JWT_SECRET;

// Never do this:
// const API_KEY = "sk-abc123"; // Hardcoded secret

Python

# Install: pip install python-dotenv
from dotenv import load_dotenv
import os

load_dotenv()

db_url = os.getenv("DATABASE_URL")
jwt_secret = os.getenv("JWT_SECRET")

PHP

// Install: composer require vlucas/phpdotenv
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

$dbUrl = $_ENV['DATABASE_URL'];
$jwtSecret = $_ENV['JWT_SECRET'];
Common AI coding mistake: AI tools often put API keys directly in frontend JavaScript files like const OPENAI_KEY = "sk-...". This ships the key to every user's browser. Any server-side secret must be loaded from environment variables and accessed only in server-side code.

Step 3 of 7

Dependency Security

AI coding tools suggest packages by name, but they sometimes hallucinate packages that do not exist. Attackers monitor these hallucinations and register the fake package names with malicious code.

Lock Files

Always commit your lock file. It pins exact dependency versions and prevents supply chain attacks through version manipulation.

# npm: commit package-lock.json
git add package-lock.json

# Python: generate and commit requirements with hashes
pip freeze > requirements.txt
pip install --require-hashes -r requirements.txt

# PHP: commit composer.lock
git add composer.lock

Audit Commands

# npm: check for known vulnerabilities
npm audit

# npm: fix automatically where possible
npm audit fix

# Python: install pip-audit and scan
pip install pip-audit
pip-audit

# PHP: check for security advisories
composer audit

Verifying Packages Are Real

# Before installing any AI-suggested npm package:
npm view package-name
# If it returns "404 Not Found" the package does not exist

# Before installing any AI-suggested pip package:
pip index versions package-name
# Or check https://pypi.org/project/package-name/

# Check download counts and repository links
# Low download counts or missing repos are red flags
Common AI coding mistake: AI tools confidently suggest packages with plausible names that do not exist on npm or PyPI. If you install them without checking, you may be installing an attacker's package. See our full guide: How to Verify AI-Suggested Packages Are Real.

Step 4 of 7

Security Headers

Security headers instruct browsers to enable built-in protections against XSS, clickjacking and content sniffing. AI tools almost never add these.

.htaccess Template (Apache)

# Security Headers
Header set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self'"
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header set X-Frame-Options "DENY"
Header set X-Content-Type-Options "nosniff"
Header set Referrer-Policy "strict-origin-when-cross-origin"
Header set Permissions-Policy "camera=(), microphone=(), geolocation=()"

# Prevent directory listing
Options -Indexes

# Prevent access to sensitive files
<FilesMatch "\.(env|log|sql|sqlite|bak|config)$">
  Order allow,deny
  Deny from all
</FilesMatch>

Express.js (Node.js)

// Install: npm install helmet
const helmet = require('helmet');
app.use(helmet());

// This sets most security headers automatically.
// Customize CSP for your needs:
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'"],
    styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
    fontSrc: ["'self'", "https://fonts.gstatic.com"],
    imgSrc: ["'self'", "data:", "https:"],
    connectSrc: ["'self'"]
  }
}));
Common AI coding mistake: AI tools set Content-Security-Policy to allow 'unsafe-inline' and 'unsafe-eval' for both scripts and styles because it eliminates CSP errors during development. In production, these directives defeat the purpose of CSP entirely.

Step 5 of 7

HTTPS Setup

Every production application needs HTTPS. Let's Encrypt provides free TLS certificates that auto-renew.

Let's Encrypt Quick Setup (Ubuntu/Debian)

# Install Certbot
sudo apt update
sudo apt install certbot python3-certbot-nginx

# Get certificate (Nginx)
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

# Or for Apache
sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com

# Verify auto-renewal
sudo certbot renew --dry-run

Force HTTPS Redirect (Nginx)

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    return 301 https://$host$request_uri;
}

If you are using Vercel, Netlify or similar platforms, HTTPS is typically enabled by default. Verify by checking that your site redirects from http:// to https://.

Common AI coding mistake: AI tools develop locally on HTTP and never configure HTTPS for production. Some generate hardcoded http:// URLs for API calls that bypass HTTPS even when the site has a certificate.

Step 6 of 7

Database Security

AI coding tools connect to databases with the simplest possible configuration, which usually means admin credentials over an unencrypted connection.

Create a Least-Privilege Database User (PostgreSQL)

-- Create a dedicated application user
CREATE USER app_user WITH PASSWORD 'strong_random_password_here';

-- Grant only necessary permissions
GRANT CONNECT ON DATABASE myapp TO app_user;
GRANT USAGE ON SCHEMA public TO app_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_user;

-- Grant sequence usage for auto-increment columns
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_user;

-- Do NOT grant: CREATE, DROP, ALTER, TRUNCATE, REFERENCES

Enable SSL Connections

# PostgreSQL connection string with SSL
DATABASE_URL=postgresql://app_user:password@host:5432/myapp?sslmode=require

# MySQL connection string with SSL
DATABASE_URL=mysql://app_user:password@host:3306/myapp?ssl=true

# MongoDB connection string with SSL
MONGODB_URI=mongodb+srv://app_user:password@cluster.example.com/myapp?retryWrites=true&ssl=true
Common AI coding mistake: AI tools use root or admin database credentials because they work immediately. They also disable SSL connections to avoid certificate configuration. In production, this means your database traffic is unencrypted and a single SQL injection gives the attacker full admin access.

Step 7 of 7

Pre-Deployment Checklist

Run through this checklist before every production deployment.

PRE-DEPLOYMENT SECURITY CHECKLIST
==================================

[ ] .env file is in .gitignore and NOT committed to the repo
[ ] All API keys and secrets are loaded from environment variables
[ ] Debug mode is OFF in production configuration
[ ] Error pages return generic messages (no stack traces)
[ ] HTTPS is enabled and HTTP redirects to HTTPS
[ ] Security headers are configured (CSP, HSTS, X-Frame-Options)
[ ] CORS is restricted to specific trusted domains
[ ] Database connects with a least-privilege user (not root)
[ ] Database connections use SSL
[ ] All dependencies are audited (npm audit / pip-audit)
[ ] Lock file is committed and up to date
[ ] Rate limiting is enabled on authentication endpoints
[ ] Password hashing uses bcrypt, scrypt or argon2
[ ] Session cookies have Secure, HttpOnly, SameSite flags
[ ] File uploads are restricted by type and size
[ ] Source maps are NOT deployed to production
[ ] Admin endpoints require proper authorization
[ ] Logging captures security events without exposing PII

For a more detailed checklist, download our free security checklist. For a full walkthrough of what happens during a professional security assessment, read What a Pentest Actually Looks Like.

Frequently Asked Questions

Setup Guide FAQs

How long does this setup take?
About 30-45 minutes if you follow each step. The version control and environment variable steps take about 10 minutes. Security headers and HTTPS take another 15 minutes. Database hardening depends on your provider but typically takes 10-15 minutes.
I already deployed. Is it too late?
It is not too late, but act quickly. Apply these steps to your current deployment immediately. If you have already committed secrets to your repository, rotate all exposed keys and consider the old ones compromised. Check your Git history for any previously committed .env files.
Does this replace a professional security audit?
No. This guide covers environment security, which is one layer of a complete security posture. It does not test for business logic flaws, authorization bypasses or application-specific vulnerabilities. A professional audit from $1,500 CAD covers the full picture.

Environment Set Up. Code Secured?

A secure environment is just the foundation.

Professional audits test what configurations cannot. From $1,500 CAD.

Order an Audit