This document outlines security best practices for configuring Protocol Guide. Never commit secrets or credentials to version control.
The following files are automatically excluded from git:
.env- Your actual secrets (NEVER commit).env.*- All environment variant files.env.example- Template only (safe to commit, no real values)
All secrets MUST be configured via environment variables. Never hardcode them in source code.
Purpose: Session cookies and authentication tokens
Generate:
# Generate a secure 32+ character secret
openssl rand -base64 32Environment Variables:
JWT_SECRET=<generated-secret-here>
NEXT_AUTH_SECRET=<generated-secret-here>Security:
- Minimum 32 characters
- Use cryptographically secure random generation
- Rotate periodically (every 90 days recommended)
- Different secrets for development/staging/production
Purpose: Gate access during beta phase
Generate:
# Generate a random uppercase code
openssl rand -hex 8 | tr '[:lower:]' '[:upper:]'Environment Variables:
EXPO_PUBLIC_BETA_ACCESS_CODE=<generated-code-here>Security:
- Should be random and unpredictable
- Rotate when compromised
- Remove this gate when going public
- Never use predictable codes like "PROTOCOL2026"
ANTHROPIC_API_KEY=sk-ant-...- Get from: https://console.anthropic.com/
- Must start with
sk-ant- - Keep server-side only
VOYAGE_API_KEY=pa-...- Get from: https://www.voyageai.com/
- Must start with
pa- - Keep server-side only
STRIPE_SECRET_KEY=sk_test_... # Development
STRIPE_SECRET_KEY=sk_live_... # Production
STRIPE_PUBLISHABLE_KEY=pk_test_... # Development
STRIPE_PUBLISHABLE_KEY=pk_live_... # Production
STRIPE_WEBHOOK_SECRET=whsec_...- Get from: https://dashboard.stripe.com/apikeys
- Use test keys for development
- Use live keys for production only
- Webhook secret from: Stripe Dashboard > Webhooks
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ...- Get from: Supabase Dashboard > Settings > API
- Service role key is highly privileged - keep secure
- Anon key is safe for client-side use
DATABASE_URL=postgresql://postgres:PASSWORD@db.your-project.supabase.co:5432/postgres- Never expose database password
- Use connection pooling in production
- Restrict to trusted networks
REDIS_URL=https://your-redis.upstash.io
REDIS_TOKEN=your_token_here- Get from: https://console.upstash.com/
- Falls back to in-memory if not configured
- Copy
.env.exampleto.env - Generate all required secrets
- Use test/development API keys
- Never commit
.envfile - Verify
.gitignoreexcludes.env
- Use separate secrets from development
- Use test Stripe keys
- Use separate database
- Enable logging for debugging
- Generate new production secrets (never reuse dev/staging)
- Use live Stripe keys
- Enable Redis for distributed rate limiting
- Set
NODE_ENV=production - Configure proper CORS origins
- Enable HTTPS only
- Rotate secrets every 90 days
- Monitor secret access logs
- Every 90 days (scheduled)
- When employee with access leaves
- Suspected compromise
- After security incident
- Before major version release
- Generate new secret
- Update in deployment platform (Netlify, etc.)
- Deploy with new secret
- Verify application works
- Invalidate old secret
- Update secret in password manager
- Hardcode secrets in source code
- Commit
.envfiles to git - Use predictable secrets like "admin123"
- Share secrets via email or Slack
- Reuse secrets across environments
- Use development secrets in production
- Store secrets in browser localStorage
- Log secrets to console or files
- Use environment variables
- Generate cryptographically secure secrets
- Use different secrets per environment
- Store secrets in password manager (1Password, Bitwarden)
- Use platform secret management (Netlify env vars)
- Rotate secrets regularly
- Audit secret access logs
- Use least-privilege principle
- Immediately rotate affected secrets
- Deploy new secrets to production
- Review access logs for unauthorized usage
- Notify affected users if data breach occurred
- Document incident in security log
- Review and update access controls
- DO NOT just delete the commit - it's still in history
- Immediately rotate ALL secrets in that file
- Use tools to purge from git history:
# Use git-filter-repo (recommended) git-filter-repo --path .env --invert-paths # Or BFG Repo-Cleaner bfg --delete-files .env
- Force push cleaned history (coordinate with team)
- Verify secrets are purged from all branches
- Notify team to re-clone repository
- 1Password - Team password manager
- Bitwarden - Open source alternative
- Netlify Env Vars - Platform-level secrets
- GitHub Secrets - For CI/CD workflows
- Doppler - Enterprise secret management
- Plain text files
- Shared Google Docs
- Slack messages
- Spreadsheets
- Review who has access to secrets
- Check for hardcoded secrets in codebase
- Verify secret rotation schedule
- Test secret revocation procedures
- Review access logs
# Scan for secrets in codebase
npm install -g detect-secrets
detect-secrets scan
# Check git history for secrets
npm install -g truffleHog
truffleHog --regex --entropy=True .gitFor security concerns or to report a vulnerability:
- Email: security@protocolguide.com
- Do not file public GitHub issues for security vulnerabilities
- Use responsible disclosure practices
- OWASP Secret Management Cheat Sheet
- NIST Password Guidelines
- Stripe Security Best Practices
- Supabase Security Best Practices
Last Updated: 2026-01-23 Version: 1.0