- Gateway access is controlled by Supabase Auth JWTs only
- Users authenticate with email and password in Supabase and must confirm their email before they can use the site
- Per-user limits are enforced as daily tick quotas stored in Supabase
- Secrets management uses environment variables and AWS Secrets Manager for production
- Supabase manages
auth.usersand sends confirmation emails on sign-up - The frontend obtains an access token from Supabase and sends it as
Authorization: Bearer <token> - The Gateway validates the token using
SUPABASE_JWT_SECRETand rejects requests when the token is invalid or the email is not confirmed
See docs/SUPABASE_SETUP.md for detailed setup instructions.
Required:
SUPABASE_URL— Your Supabase project URLSUPABASE_ANON_KEY— Publishable/anon key (NOT service role key) - use this for RLSSUPABASE_JWT_SECRET— JWT secret for verifying user tokens
Optional:
SUPABASE_ALLOW_UNCONFIRMED— Set to"true"to allow unconfirmed emails in development
How to get SUPABASE_JWT_SECRET:
- Go to your Supabase project dashboard: https://supabase.com/dashboard
- Navigate to Settings → API
- Scroll down to the JWT Settings section
- Copy the
JWT_SECRETvalue (this is yourSUPABASE_JWT_SECRET)
Setting environment variables: These values are treated as secrets and should only be provided via environment or Docker compose files, never committed to source control. The gateway container loads environment variables from:
.envfile (in theservices/directory)keys.envfile (in theservices/directory)
Add SUPABASE_JWT_SECRET=<your-secret> to one of these files to make it available to the gateway container.
- Each user has a profile row in the
profilestable withdaily_tick_limit(default 32) - Daily usage is tracked in
user_daily_usagekeyed by(user_id, usage_date) - On each
/taskscall, the Gateway subtractsmax_ticksfrom the user's remaining ticks and rejects the call with429when the quota is exhausted - Row-Level Security (RLS): The
profilesanduser_daily_usagetables use RLS policies. See docs/SUPABASE_SETUP.md for setup instructions.
Local: API keys in services/keys.env (not committed), env vars in services/.env, loaded by Docker Compose
AWS: Secrets via AWS Secrets Manager, use scripts/env-to-ecs.py to generate, task definitions reference secrets, no secrets in images
RabbitMQ/Redis use standard protocols (not encrypted locally). External APIs use HTTPS. ChromaDB uses HTTP locally.
For AWS production: VPC isolation, TLS/SSL for inter-service communication, encrypted EBS volumes.