Skip to content

Environment Variable Inventory ​

Executive Overview — all summaries for decision-makers.

No secrets in this document. Set values only in Render Dashboard / Azure / Cloudflare.

Production — Backend (mqa-backend) ​

VariableRequiredDescriptionSource
DATABASE_URL✅PostgreSQL connection stringRender Postgres (auto)
NODE_ENV✅productionrender.yaml
PORT✅3000render.yaml
JWT_SECRET✅JWT signing (min. 32 characters)Render generate
CORS_ORIGIN✅https://portal.mqa.grouprender.yaml
FRONTEND_URL✅https://portal.mqa.grouprender.yaml
CRON_SECRET✅Header x-cron-secret for /api/jobs/runRender generate
SKIP_OAUTH_VALIDATION✅Must be false in productionrender.yaml
OAUTH_CLIENT_ID✅Azure App RegistrationAzure Portal
OAUTH_CLIENT_SECRET✅Azure App SecretAzure Portal
OAUTH_TENANT_ID✅Azure Tenant IDAzure Portal
OAUTH_REDIRECT_URI✅https://api.mqa.group/api/auth/callbackAzure + Render
ANTHROPIC_API_KEY✅Claude APIAnthropic Console — see AI-SERVICES
OPENROUTER_API_KEY⚪Alternative LLM routeOpenRouter — see AI-SERVICES
RESEND_API_KEY⚪Email via ResendResend — see RESEND
MICROSOFT_SENDER_EMAIL⚪Graph email senderAzure
R2_ACCOUNT_ID✅Cloudflare R2 accountCloudflare (MQA org)
R2_ACCESS_KEY_ID✅R2 API keyCloudflare
R2_SECRET_ACCESS_KEY✅R2 API secretCloudflare
R2_BUCKET_NAME✅e.g. mqa-mediaCloudflare
R2_PUBLIC_URL✅Public R2 CDN URLCloudflare
ADMIN_MAINTENANCE_SECRET⚪/api/admin/maintenance/*openssl rand
EMAIL_WEBHOOK_SECRET⚪/api/email-tracking/deliveredopenssl rand
OPENSANCTIONS_API_KEY⚪KYC screeningOpenSanctions
HIDE_PORTAL_DEMO_CONTENT⚪Hide demo contenttrue in prod

Production — Frontend (mqa-frontend) ​

VariableRequiredDescription
VITE_API_BASE_URL✅https://api.mqa.group/api
VITE_APP_ENV✅production
VITE_DOCS_URL✅https://docs.mqa.group (external VitePress site)
NODE_VERSION✅20

Never put secrets under VITE_* — they end up in the browser bundle.

Production — Developer Docs (mqa-docs) ​

VariableRequiredDescription
DOCS_PASSWORD✅HTTP Basic Auth password for docs.mqa.group — site is public if unset
DOCS_USERNAME⚪Basic Auth username (default mqa)
PORT✅Set by Render automatically
NODE_VERSION✅20

Service runs apps/docs-site/server.mjs after VitePress build. Share username/password with MANAGEMENT+ / auditors as needed.

Staging (planned) ​

Same keys as production, different values:

  • CORS_ORIGIN / FRONTEND_URL → https://staging.portal.mqa.group
  • VITE_API_BASE_URL → https://staging.api.mqa.group/api
  • Own DATABASE_URL, JWT_SECRET, OAuth app

Local Development ​

FileGit
backend/.env❌ gitignored
.env.local❌ gitignored
backend/ENV_TEMPLATE.txt✅ template

Rotation ​

SecretRecommended frequencyTrigger
JWT_SECRET12 monthsInvalidates all sessions
CRON_SECRET12 monthsUpdate Render Cron Job header
R2 keysOn account migrationImmediately
OAuth secret24 months (Azure policy)Azure Portal
ADMIN_MAINTENANCE_SECRETOn team changeManual

See SECURITY-STATUS.