-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.env.example
More file actions
112 lines (103 loc) · 4.52 KB
/
Copy path.env.example
File metadata and controls
112 lines (103 loc) · 4.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# Database
# Railway runtime: use Supavisor session mode (port 5432) with a dedicated role.
# Append connection_limit=3&pool_timeout=10&connect_timeout=10 to the Railway URL
# (use & instead of ? when the URL already has query parameters). If local
# development must share the production database, use connection_limit=1.
DATABASE_URL="set-to-the-Supabase-session-pooler-URL"
# Railway web: set this to the same restricted URL as DATABASE_URL because
# Prisma 5 validates it during `prisma generate`. Use the real migration-owner
# URL only in the separately controlled migration job/CI or trusted local admin.
DIRECT_URL="set-to-runtime-URL-in-web-or-owner-URL-in-migration-environment"
# Supabase
NEXT_PUBLIC_SUPABASE_URL=...
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=....
SUPABASE_URL=....
SUPABASE_PUBLISHABLE_KEY=....
SUPABASE_SECRET_KEY=....
SUPABASE_RESOURCE_BUCKET="resources-private"
# AI
OPENAI_API_KEY="your-openai-api-key"
AI_CHAT_PROVIDER="openai"
AI_CHAT_MODEL="gpt-4o-mini"
AI_GROUNDED_CHAT_ENABLED="false"
AI_GROUNDING_PIPELINE="legacy"
AI_EMBEDDING_PROVIDER="openai"
AI_EMBEDDING_MODEL="text-embedding-3-small"
AI_EMBEDDING_DIMENSIONS="1536"
AI_EMBEDDING_VERSION="1"
RECOMMENDATIONS_CRON_SECRET="replace-me"
# Independent secret for the scheduled permanent-account purge endpoint.
ACCOUNT_DELETION_CRON_SECRET="replace-with-at-least-32-random-bytes"
AI_DAILY_USER_QUOTA="50"
AI_RATE_LIMIT_ACCOUNT_PER_MINUTE="15"
AI_RATE_LIMIT_IP_PER_MINUTE="30"
OPENAI_TIMEOUT_MS="25000"
# Distributed hard stop across every web replica. Uses a UTC calendar day.
AI_GLOBAL_BUDGET_ENABLED="true"
AI_GLOBAL_DAILY_TOKEN_BUDGET="1000000"
# Monthly reporting-service only: an OpenAI organization Admin API key is
# required by the Costs API. Do not expose it to browser code. Prefer setting
# it only on the isolated Railway cron service, not the web service.
OPENAI_ADMIN_KEY=""
OPENAI_ORGANIZATION_ID=""
# Optional: limit the reported organization costs to this OpenAI project.
OPENAI_COST_PROJECT_ID=""
AI_MONTHLY_COST_ALERT_USD=""
# Security and abuse controls
RATE_LIMIT_HASH_SECRET="replace-with-at-least-32-random-bytes"
# Password-reset abuse warnings default to one per account per 24 hours. The
# review link lasts 30 minutes and a confirmed provider lock lasts 24 hours.
PASSWORD_RESET_ABUSE_ALERT_COOLDOWN_HOURS="24"
PASSWORD_RESET_ABUSE_ALERT_DAILY_CAP="1"
PASSWORD_RESET_LOCK_REVIEW_TTL_MINUTES="30"
PASSWORD_RESET_SECURITY_LOCK_HOURS="24"
# Password-reset limits share one fixed window. The high IP ceiling avoids
# blocking a school or household whose users share one public address.
PASSWORD_RESET_RATE_LIMIT_ACCOUNT_MAX="3"
PASSWORD_RESET_RATE_LIMIT_IP_MAX="300"
PASSWORD_RESET_RATE_LIMIT_GLOBAL_MAX="1000"
PASSWORD_RESET_RATE_LIMIT_WINDOW_MS="3600000"
# railway | cloudflare | vercel | direct. Do not trust arbitrary proxy headers.
TRUSTED_PROXY_PROVIDER="railway"
APP_ORIGIN="https://your-real-domain.com"
# Railway cron service only: target the web service over private networking.
# Plain HTTP is accepted only for an exact *.railway.internal hostname.
ACCOUNT_LIFECYCLE_CRON_ORIGIN=""
# Optional comma-separated exact origins for intentional alternate frontends.
CSRF_TRUSTED_ORIGINS=""
AUTH_RATE_LIMIT_ACCOUNT_MAX="300"
AUTH_RATE_LIMIT_IP_MAX="600"
AUTH_RATE_LIMIT_WINDOW_MS="300000"
EXTERNAL_REQUEST_TIMEOUT_MS="15000"
# Monthly security-operations evidence and email report.
SECURITY_AUDIT_DB_ENABLED="true"
SECURITY_REPORT_RECIPIENTS="security@studybuddyng.com"
SECURITY_REPORT_LOGIN_FAILURE_THRESHOLD="25"
SECURITY_REPORT_RATE_LIMIT_THRESHOLD="50"
# Transactional guardian-authorisation email (separate from Supabase Auth SMTP).
RESEND_API_KEY="replace-me"
TRANSACTIONAL_EMAIL_FROM="Study Buddy Privacy <no-reply@updates.studybuddyng.com>"
TRANSACTIONAL_EMAIL_REPLY_TO="privacy@studybuddyng.com"
GUARDIAN_AUTHORIZATION_TTL_HOURS="72"
ACCOUNT_DELETION_CONFIRMATION_TTL_HOURS="24"
# Upload security. Scanning defaults to required in production and optional elsewhere.
MALWARE_SCAN_REQUIRED="true"
CLAMAV_HOST="clamav.railway.internal"
CLAMAV_PORT="3310"
CLAMAV_TIMEOUT_MS="20000"
# Ghostscript reconstructs PDFs before the sanitized bytes are stored.
PDF_CDR_REQUIRED="true"
PDF_CDR_COMMAND="gs"
PDF_CDR_TIMEOUT_MS="20000"
PDF_CDR_MAX_OUTPUT_BYTES="31457280"
# Payments
PAYSTACK_SECRET_KEY="sk_test_or_live_key"
# CAPTCHA
NEXT_PUBLIC_CAPTCHA_ENABLED="false"
NEXT_PUBLIC_CAPTCHA_PROVIDER="hcaptcha"
NEXT_PUBLIC_CAPTCHA_SITE_KEY="your-captcha-site-key"
# WhatsApp
WHATSAPP_VERIFY_TOKEN="replace-me"
WHATSAPP_ACCESS_TOKEN="replace-me"
WHATSAPP_APP_SECRET="replace-me"
WHATSAPP_PHONE_NUMBER_ID="replace-me"