AuthConfig
The Auth constructor takes a partial AuthConfig. Options are deep-merged over defaults. The hosted service and the template expose these as environment variables.
Session
| Option | Default | Description |
session.expiresIn | 7 days | Access token lifetime |
session.idleTimeout | 4 hours | Session expires after inactivity |
session.absoluteLifetime | 30 days | Hard ceiling on session lifetime |
session.maxConcurrentSessions | 10 | Oldest sessions are revoked beyond this |
Rate limiting
| Option | Default | Description |
rateLimit.maxAttempts | 10 | Sign-in attempts before throttling |
rateLimit.windowMs | 15 minutes | Rate limit window |
Captcha
| Option | Description |
captcha.provider | none, hcaptcha, or turnstile |
captcha.siteKey | Public widget key |
captcha.secret | Server-side verification secret |
Captcha providers
| Provider | Supported | Notes |
| hCaptcha | ✅ | Default. Has a known Safari/WebKit issue where api.hcaptcha.com/authenticate returns 401 due to third-party storage isolation. |
| Turnstile | ✅ | Recommended for Safari-heavy deployments. No known WebKit incompatibility. |
RBAC
Permissions are strings in the form resource:action (for example admin:panel). Users carry a role and a permission list. Defaults for roles can be set in config.rbac. The admin role bypasses permission checks.
Environment variables
Used by the hosted service and the fullstack template. See .env.example in the repository for the complete list.
| Variable | Purpose |
DATABASE_URL | Postgres connection string |
CAPTCHA_PROVIDER | Captcha provider (none disables) |
HCAPTCHA_SITE_KEY, CAPTCHA_SECRET | hCaptcha keys |
TURNSTILE_SITE_KEY, TURNSTILE_SECRET | Turnstile keys |
SESSION_EXPIRES_IN and friends | Session lifetimes in milliseconds |
RATE_LIMIT_MAX_ATTEMPTS, RATE_LIMIT_WINDOW_MS | Rate limits |
RESEND_API_KEY, RESEND_FROM | Password-reset email |
ALLOWED_ORIGIN | CORS origin |
PUBLIC_BASE_URL | Base URL used in generated links |
Sensitive values are always injected through environment variables or configuration. They are never hardcoded or committed.