Skip to content

Environment Variables

Never commit .env files

All environment files are in .gitignore. Never commit render.env, sendgrid.env, or any file containing secrets to Git.


Files

File Used In Purpose
render.env Production (Render) All production secrets
sendgrid.env Local development Local dev secrets (DB, S3, email)
.flaskenv Local dev only Flask dev server config

Detection: python if os.getenv("RENDER"): load_dotenv("render.env") else: load_dotenv("sendgrid.env")


Required Variables

Database

Variable Description
DATABASE_URL PostgreSQL connection URL (production)
INTERNAL_DATABASE_URL Render internal DB URL (faster, no SSL)
USE_INTERNAL_DB Set to true to use internal URL
LOCAL_DB_PATH SQLite file path (local dev only)

Wasabi S3

Variable Description
WASABI_ACCESS_KEY Wasabi IAM access key ID
WASABI_SECRET_KEY Wasabi IAM secret access key
WASABI_BUCKET_NAME S3 bucket name
WASABI_ENDPOINT_URL https://s3.ap-southeast-1.wasabisys.com
WASABI_REGION ap-southeast-1

Encryption

Variable Description
MASTER_KEY 64 hex chars (32 bytes) — master AES-256 key for wrapping per-user keys

MASTER_KEY is critical

If MASTER_KEY is lost or changed, all encrypted files become permanently unreadable. Store it in a secure secrets manager (e.g., Render Secrets, 1Password). Never rotate without re-encrypting all user keys.

Flask

Variable Description
SECRET_KEY Flask session signing key (random 32+ bytes)
FLASK_ENV production or development
FLASK_DEBUG 0 in production

Email (Brevo SMTP)

Variable Description
BREVO_SMTP_SERVER smtp-relay.brevo.com
BREVO_SMTP_PORT 587
BREVO_SMTP_LOGIN Brevo account email
BREVO_SMTP_PASSWORD Brevo SMTP key
SENDER_EMAIL From address for all emails

Redis / Celery

Variable Description
REDIS_URL Redis connection URL for Celery broker + result backend

Razorpay

Variable Description
RAZORPAY_KEY_ID Razorpay API key ID
RAZORPAY_KEY_SECRET Razorpay API secret

Admin

Variable Description
ADMIN_EMAIL Primary admin email for OTP login

Local vs Production Differences

Variable Local (sendgrid.env) Production (render.env)
DATABASE_URL SQLite path PostgreSQL URL
FLASK_DEBUG 1 0
FLASK_ENV development production
WASABI_* Same (shared bucket) Same
MASTER_KEY Same (shared key) Same

TL;DR

Critical secrets: MASTER_KEY (encryption), WASABI_ACCESS_KEY/WASABI_SECRET_KEY (storage), SECRET_KEY (sessions), DATABASE_URL (database). Never lose: MASTER_KEY — losing it means all encrypted files are unrecoverable. Local vs prod: Different DATABASE_URL and Flask debug settings. All other secrets are the same.