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 and the IP block skip. An IP that fails 20 times in a row (a wrong password or code, or a rate limit hit), each within 15 minutes of the last, is shut out of the API for an hour. |
TRUSTED_PROXIES | none | IPs or CIDRs trusted to supply X-Forwarded-For. Set it behind a reverse proxy, or the rate limit and the IP block count the proxy instead of the visitor, and one visitor's failures block everyone. |
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. Required in the Cloud Edition; the Community Edition may leave it and RESEND_API_KEY empty, which turns off password reset and magic-link sign-in (change SUPER_USER to reset the password). |
RESEND_API_KEY | none | Resend API key. Required with FROM_ADDRESS. |
GOOGLE_CLIENT_ID | none | Google OAuth client. Empty disables Google sign-in. |
GOOGLE_CLIENT_SECRET | none | Google OAuth secret. |
LEMONSQUEEZY_API_KEY | none | Cloud Edition: the Lemon Squeezy API key that takes payments for plans (a test-mode key for the store's test mode). Empty leaves checkout off. The API reads the store when it starts and refuses to start if it cannot. |
LEMONSQUEEZY_STORE_ID | none | The numeric id of the store that sells the plans. Its catalog is the plans: one per variant, at the variant's price, synced when the API starts, every 15 minutes, and when a super user calls POST /api/v1/plans/sync. Each new account is saved as one of its customers. Required with LEMONSQUEEZY_API_KEY. |
LEMONSQUEEZY_WEBHOOK_SECRET | none | The signing secret of the store's webhook, pointed at $AUTH_BASE_URL/api/v1/billing/lemonsqueezy/webhook with order_created, order_refunded, subscription_created and subscription_updated. Required with LEMONSQUEEZY_API_KEY. |
REQUIRE_PAID_SHARING | false | Cloud Edition: sharing an item needs a paid plan. Needs LEMONSQUEEZY_API_KEY; the API refuses to start without it, so a missing key never makes sharing free unnoticed. |
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.