Secrets Management
Secret management, rotation procedures, and environment variable security
Secrets Management
All secrets for José Madrid Salsa are stored as Vercel environment variables. No secrets are committed to the repository.
Secret Inventory
| Secret | Variable | Rotation Frequency |
|---|---|---|
| Database password | DATABASE_URL | On compromise |
| Auth session key | NEXTAUTH_SECRET | On compromise |
| Admin encryption | MASTER_KEY | On compromise |
| Data encryption | ENCRYPTION_KEY | On compromise |
| Stripe API key | STRIPE_SECRET_KEY | Annually or on compromise |
| Stripe webhook secret | STRIPE_WEBHOOK_SECRET | On endpoint change |
| Resend API key | RESEND_API_KEY | On compromise |
| Google service account key | GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY | Annually |
| Sentry auth token | SENTRY_AUTH_TOKEN | Build-time only, on compromise |
| UploadThing secret | UPLOADTHING_SECRET | On compromise |
| Anthropic API key | ANTHROPIC_API_KEY | On compromise |
Generating Secrets
Hex Secrets (MASTER_KEY, NEXTAUTH_SECRET)
openssl rand -hex 32Base64 Secrets (ENCRYPTION_KEY)
node -e "console.log(require('crypto').randomBytes(64).toString('base64'))"Vercel CLI
# Add a secret to production
vercel env add SECRET_NAME production
# Remove and re-add to rotate
vercel env rm SECRET_NAME production
vercel env add SECRET_NAME productionPre-Commit Protection
Gitleaks runs on every commit to prevent accidental secret exposure:
# Scan the entire repo
npm run security:scan
# Scan only staged changes (runs automatically via pre-commit hook)
npm run security:protect
# Generate a baseline report
npm run security:baselineThe pre-commit hook chain is:
git commit → husky pre-commit → lint-staged → gitleaks protectDo not skip hooks
Never use git commit --no-verify to bypass the secret scanning hook. If Gitleaks flags a false positive, add it to a .gitleaksignore file instead.
Rotation Procedure
Generate a new secret value
Use the appropriate generation command for the secret type.
Update in Vercel
vercel env rm SECRET_NAME production
vercel env add SECRET_NAME productionOr update via the Vercel Dashboard: Project Settings > Environment Variables.
Trigger redeployment
vercel --prodOr push an empty commit:
git commit --allow-empty -m "chore: trigger redeploy for secret rotation"
git push origin mainVerify the deployment
Check that the new deployment starts correctly and the application functions normally.
Revoke the old secret
For third-party services (Stripe, Resend, Google), revoke the old key in their respective dashboards after confirming the new key works.
Environment Isolation
Secrets should differ across environments:
| Variable | Production | Preview | Development |
|---|---|---|---|
NEXTAUTH_SECRET | Unique | Unique | Unique |
STRIPE_SECRET_KEY | sk_live_... | sk_test_... | sk_test_... |
DATABASE_URL | Production Neon | Branch/dev Neon | Local Postgres |
MASTER_KEY | Unique | Unique | Unique |
Never share production secrets
Production secrets must never be reused in preview or development environments. A compromised preview deployment should not grant access to production data.
.env Files
The repository contains several .env template files:
| File | Purpose | Committed |
|---|---|---|
.env.example | Template with placeholder values | Yes |
.env.local | Local development values | No (gitignored) |
.env.vercel.production | Pulled from Vercel | No (gitignored) |
Pull production variables locally for debugging:
npm run db:production:pull-env
# or: vercel env pull .env.vercel.production --environment=production --yesHow is this guide?
Last updated on