Configuration
Every setting of the API, the web app and the extension.
API
Each setting of apps/server is an environment variable, or the command-line
flag of the same name in kebab-case (go run ./cmd/api -h).
| Variable | Default | Purpose |
|---|---|---|
ENV | production | development, staging or production. Only development relaxes the session cookie and exempts loopback from the rate limit. |
DEBUG | false | Logs every auth query with its values. Refused when ENV=production. |
PORT | 8080 | Port the API listens on. |
APP_NAME | montara-pass | Name used in auth emails. |
APP_SECRET | none | Required, at least 32 characters. Signs sessions and tokens. |
DB_DSN | none | Required. PostgreSQL 18 connection string. |
DB_MAX_OPEN_CONNS | 25 | Connection pool size. |
DB_MAX_IDLE_CONNS | 25 | Idle connections kept. |
DB_MAX_IDLE_TIME | 15m | How long an idle connection is kept. |
MIGRATE_ON_BOOT | false | Apply the embedded migrations before serving. |
SEED_ON_BOOT | false | Run the idempotent seeders before serving. Needs SUPER_USER. |
SUPER_USER | none | email:password of the super user to seed. |
CORS_ALLOWED_ORIGINS | none | Comma-separated browser origins. Empty means same-origin only, which is enough when the API serves the web app. |
RATE_LIMIT_EXEMPT_IPS | none | Comma-separated client IPs the rate limiter skips. |
TRUSTED_PROXIES | none | IPs or CIDRs trusted to supply X-Forwarded-For. Set it behind a reverse proxy, or the rate limit counts the proxy instead of the visitor. |
AUTH_BASE_URL | http://localhost:$PORT | Public URL of the API, used in email links and the Google callback. |
FROM_ADDRESS | none | Sender of auth emails. Must be a domain verified in Resend. |
RESEND_API_KEY | none | Resend API key. |
GOOGLE_CLIENT_ID | none | Google OAuth client. Empty disables Google sign-in. |
GOOGLE_CLIENT_SECRET | none | Google OAuth secret. |
REDIS_URL | none | Redis for what replicas must share: rate limit counts and idempotent answers, e.g. redis://redis:6379/0 (rediss:// for TLS). Empty keeps them in the process's memory, which is enough for one instance. The API refuses to start when it is set and Redis does not answer. |
SENTRY_DSN | none | Sentry DSN for error reports. |
The Google redirect URI to register is
$AUTH_BASE_URL/api/v1/auth/oauth2/callback/google.
Browser extensions are a special case of CORS: the API accepts requests
whose origin starts with chrome-extension:// or moz-extension:// without
listing them.
Web app
apps/app reads its variables at build time: Vite inlines them into the
bundle.
| Variable | Default | Purpose |
|---|---|---|
VITE_API_URL | the page's own origin | Origin of the API. Leave it empty unless the app is hosted somewhere else than the API. |
VITE_APP_NAME | Montara Pass | Name shown in the UI. |
VITE_API_PROXY_TARGET | http://localhost:8080 | Development only: where the Vite dev server proxies /api. |
Browser extension
apps/extension reads its defaults at build time from apps/extension/.env.
Without that file a development build (watch) uses the local servers and a
production build uses https://app.montarapass.com for both.
| Variable | Development | Purpose |
|---|---|---|
VITE_DEFAULT_API_URL | http://localhost:8080 | Origin of the API. |
VITE_DEFAULT_APP_URL | http://localhost:5173 | The web app that "Open web app" links to. |
A production build's Settings offer one Server URL behind a Self-hosted switch; a development build's show both URLs.