Backend Environment Variables
The backend API (FastAPI) uses these environment variables, defined inathena-api/app/config.py.
Environment
Deployment environment. Must be one of:
development- Local development modestaging- Staging/testing environmentproduction- Production deployment
production for live deployments.Database
PostgreSQL connection string using asyncpg driver.Format:
postgresql+asyncpg://user:password@host:port/databaseExamples:- Local:
postgresql+asyncpg://athena:athena_dev@localhost:5432/athena_db - Supabase:
postgresql+asyncpg://postgres.xxxx:[email protected]:6543/postgres
Authentication & JWT
Secret key for signing JWT tokens.Requirements:
- Minimum 32 characters
- Use a cryptographically secure random string
- Never commit to version control
Algorithm for JWT token signing. Default is
HS256 (HMAC-SHA256).JWT token expiration time in minutes.Recommendations:
- Development: 60-120 minutes
- Production: 15-30 minutes
CORS Configuration
Comma-separated list of allowed origins for Cross-Origin Resource Sharing.Format:
https://domain1.com,https://domain2.comExamples:- Development:
http://localhost:3000,http://localhost:5173 - Production:
https://athena.yourdomain.com,https://app.yourdomain.com
Supabase (Optional)
These are optional but recommended for production deployments using Supabase.Supabase project URL.Format:
https://xxxx.supabase.coFound in Supabase Dashboard → Settings → APISupabase anonymous/public API key.Found in Supabase Dashboard → Settings → API
This key is safe to use in frontend code.
Supabase service role key with elevated permissions.Found in Supabase Dashboard → Settings → API
Cloudflare R2 Storage (Optional)
Required for document upload features (Phase 2+).Cloudflare R2 endpoint URL.Format:
https://xxxx.r2.cloudflarestorage.comFound in Cloudflare Dashboard → R2 → Bucket → SettingsR2 access key ID for authentication.Created in Cloudflare Dashboard → R2 → Manage R2 API Tokens
R2 secret access key for authentication.
Name of the R2 bucket for storing uploaded documents.
Error Tracking
Sentry Data Source Name for error tracking.Format:
https://[email protected]/xxxxOptional but highly recommended for production.Superadmin Creation (CI/CD)
These variables are used by thecreate_superadmin.py script for automated admin user creation.
UUID for the superadmin user (should match Supabase auth.users id).
Email address for the superadmin user.
Full name for the superadmin user.
Optional school UUID to create a membership for.
Comma-separated membership roles (e.g.,
superadmin,rector).Frontend Environment Variables
The frontend (React + Vite) uses these environment variables, prefixed withVITE_.
API Configuration
Backend API base URL.Examples:
- Local development:
http://localhost:8000 - Production:
https://api.yourdomain.com
No trailing slash. The frontend will append paths like
/api/v1/auth/login.Supabase (Optional)
Supabase project URL (same as backend
SUPABASE_URL).Format: https://xxxx.supabase.coSupabase anonymous key (same as backend
SUPABASE_ANON_KEY).Safe to expose in frontend. This is a public key with limited permissions.
Environment File Examples
Backend (.env)
Frontend (.env)
Validation
After configuring environment variables, verify your setup:Backend
Frontend
Security Best Practices
- Never commit
.envfiles - Add to.gitignore - Use different secrets per environment - Dev, staging, and prod should have unique secrets
- Rotate secrets regularly - Especially after team member departures
- Limit access - Only give service role keys to backend services
- Use secret management - Consider using services like AWS Secrets Manager, Doppler, or your platform’s secret manager
- Audit regularly - Check who has access to production secrets
Troubleshooting
Common Issues
“JWT decode error”- Ensure
JWT_SECRETmatches between backend and Supabase (if using Supabase auth) - Check that the secret is the same in all backend instances
- Verify frontend URL is in
CORS_ORIGINS - Ensure no trailing slashes in URLs
- Check protocol matches (http vs https)
- Verify
DATABASE_URLformat is correct - Check database is accessible from your hosting environment
- For Supabase, ensure you’re using the correct pooler port (6543 for Transaction mode)
- Confirm variable is set in your hosting platform’s dashboard
- Check variable name matches exactly (case-sensitive)
- Restart the service after adding new variables